網頁

2014年6月11日 星期三

[Visual Studio 2012] Common controls 不見了

 

用 MFC 來寫一些對話盒, 執行一些簡單的動作, 是很方便的事. MFC 提供的一些 common control, 讓這些動作變得更簡單. 如果 common control 不能使用, 那根本是全殘了. 不知道為什麼發生這種事, 不過如果遇到, 可以參考以下的解決辦法.

image

解決的辦法是刪除 C:\Documents and Settings\[username]\Local Settings\Application Data\Microsoft\VisualStudio\11.0, 裡面的 .tbd 檔案.

不過, 這個說來簡單, 但是做起來會有一些小麻煩.

1. 找不到 Documents and Settings 這個目錄. 在 Windows 中, 這個目錄預設是隱藏的. 在控制台中, 選擇 外觀及個人化, 裡面的資料夾選項 : 取消隱藏保護的作業系統檔案, 並勾選顯示隱藏的檔案, 資料夾及磁碟機. 這樣就可以在 Windows 安裝的磁碟, 看到 Documents and Settings 的目錄了.

image

 

2. 打不開 Documents and Settings 這個目錄.

image

在 Documents and Settings 這個目錄上按右鍵, 以啟動資料夾選項, 切換到安全性的分頁

image

按進階, 以進入進階設定

image

按變更權限, 以變更存取權限

image

選擇 “Everyone” , 也就是被拒絕的那一個, 並按下編輯,把原本拒絕那一欄打勾的列出資料夾/讀取資料

image

然後按很多次套用和確定, 回到資料夾. 在到達目標資料夾前, 還會遇到幾次的拒絕存取, 用同樣的方法過關. 最後終於到達目的地.

 image

殺掉 2 個 .tbd 檔案, 以及 2 個 .dat 檔案. 重新開啟 Visual 2012, common control 回來了.

image

[EZ-USB FX3] Create new project


雖然 FX3 SDK 提供了很多 example, 但是當要進行自己的工作時, 還是會想要建一個自己的專案, 至少專案名稱是自己想要的.
不過, FX3 在這方面不太好操作, 自己 create 出來的專案, 完全不能用. 以下說明如何以手動的方式建立一個新的專案

建立專案資料夾

在 FX3 的範例目錄下, ex: C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples, 建立一個新的資料夾, 資料夾名稱就是專案名稱. 在這個例子中是 CxTest
image

複製專案檔案

從一個已經存在的專案範本中, 複製專案內容. 以下是從 cyfxbulksrcsink 複製. 將 cyfxbulksrcsink 下的檔案, 都複製到 CxTest 的目錄.
image

重新命名專案檔案

將 cyfxbulksrcsink.c 重新命名成 CxTest.c
將 cyfxbulksrcsink.h 重新命名成 CxTest.h
將 cyfxbulkdscr.c 重新命名成 CxTestDscr.h
其他的檔案是每一個專案都有, 而且內容一樣的.

修改專案檔案內容

1. 修改 CxTest.c
將 #include "cyfxbulksrcsink.h" 修改為 #include "CxTest.h" 
2. 修改 CxTestDscr.c
將 #include "cyfxbulksrcsink.h" 修改為 #include "CxTest.h"
3. 修改 .project
將 cyfxbulksrcsink 全部取代成 CxTest
4. 修改 .cproject
將 cyfxbulksrcsink 全部取代成 CxTest

import 專案範例

在 File/Import/Existing Projects into Workspace
image
瀏覽至 C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples\CxTest
image
然後就可以在 project explorer 中, 看到新增加的專案
image

2014年6月3日 星期二

[EZ-USB FX3] UART on Development Kit


從 Uart 印一些 message 作 debug 用, 是 firmware 常用的開發技巧. FX3 所附的範例中, 也有一些有印出 debug message, 不過, 實際上操作, Uart 卻是一片空白. 以下用一步一步的操作, 來確認 Uart 的問題.

1. 檢查 Uart 裝置.

現在很多電腦都沒有 Uart/RS232/COM port 這樣的介面, 取而代之的, 是 Uart-USB 的裝置很容易取得. 以下就使用 Uart-USB 來代替 UART 的輸出.
在控制台, 裝置管理員, 可以看到連接埠, 下圖中的 COM10, 就是我們要用的 Uart port.
image

2. 開啟 PC 端的終端機.

不管是用 Hyper Terminal, 或是其他隨便什麼軟體, Uart 都有一些設定要做, 不過很簡單.Port name (COM10), Speed/baud rate (115200), Data bits (8), Stop bits (1), Parity (None),Flow control (None )
image

3. 設定 DVK ( developmen kit ) 上面的 jumper.

J101 1 and 2, GPIO_46=UART_RTS, J101 用來設定 GPIO 46 當作 UART_RTS
J102 1 and 2, GPIO_47=UART_CTS, J102 用來設定 GPIO 47 當作 UART_CTS
J103 1 and 2, GPIO_48=UART_TX, J103 用來設定 GPIO 48 當作 UART_TX
J104 1 and 2, GPIO_49=UART_RX, J104 用來設定 GPIO 49 當作 UART_RX 實際上, CTS/RTS 現在已經很少用到, 所以只跳 J103/J104 也是可以的.
image

4. 開啟 USBDebug 範例. Build 完 project.

update 到 DVK 上, 嗯, 還是不 work.
image

5. 修改 USBDebug 範例.

1. cyfxusbdebug.c 的 main()
UART 的 GPIO 的設定應該和以下的程式碼相同. 如果都沒有改過, 應該是一樣的.
/* No LPP or GPIO is being used. */
io_cfg.isDQ32Bit = CyFalse;
io_cfg.s0Mode = CY_U3P_SPORT_INACTIVE;
io_cfg.s1Mode = CY_U3P_SPORT_INACTIVE;
io_cfg.useUart   = CyTrue;
io_cfg.useI2C    = CyFalse;
io_cfg.useI2S    = CyFalse;
io_cfg.useSpi    = CyFalse;
io_cfg.lppMode   = CY_U3P_IO_MATRIX_LPP_UART_ONLY;
/* No GPIOs are enabled. */
io_cfg.gpioSimpleEn[0]  = 0;
io_cfg.gpioSimpleEn[1]  = 0;
io_cfg.gpioComplexEn[0] = 0;
io_cfg.gpioComplexEn[1] = 0;
status = CyU3PDeviceConfigureIOMatrix (&io_cfg);
if (status != CY_U3P_SUCCESS)
{
    goto handle_fatal_error;
}
以上是設定的 Uart 的 IO. 但是 UART 的 config 卻沒有設, 因此要加入一個 function CyFxDebugInit ()
2. 加入 CyFxDebugInit ()
/* This function initializes the debug module. The debug prints
* are routed to the UART and can be seen using a UART console
* running at 115200 baud rate. */
void CyFxDebugInit (void)
{
    CyU3PUartConfig_t uartConfig;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
    /* Initialize the UART for printing debug messages */
    apiRetStatus = CyU3PUartInit();
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        /* Error handling */
        CyFxAppErrorHandler(apiRetStatus);
    }
    /* Set UART configuration */
    CyU3PMemSet ((uint8_t *)&uartConfig, 0, sizeof (uartConfig));
    uartConfig.baudRate = CY_U3P_UART_BAUDRATE_115200;
    uartConfig.stopBit = CY_U3P_UART_ONE_STOP_BIT;
    uartConfig.parity = CY_U3P_UART_NO_PARITY;
    uartConfig.txEnable = CyTrue;
    uartConfig.rxEnable = CyFalse;
    uartConfig.flowCtrl = CyFalse;
    uartConfig.isDma = CyTrue;
    apiRetStatus = CyU3PUartSetConfig (&uartConfig, NULL);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }
    /* Set the UART transfer to a really large value. */
    apiRetStatus = CyU3PUartTxSetBlockXfer (0xFFFFFFFF);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }
    /* Initialize the debug module. */
    apiRetStatus = CyU3PDebugInit (CY_U3P_LPP_SOCKET_UART_CONS, 8);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }
    CyU3PDebugPreamble (CyFalse); }
3. 呼叫 CyFxDebugInit()
在 ApplnThread_Entry() 中, 呼叫 CyFxDebugInit () /* Entry function for the AppThread. */
void
ApplnThread_Entry ( uint32_t input)
{
    CyFxDebugInit();
    /* Initialize the logger application */
    CyFxApplnInit();
    for (;;)
    {
        CyU3PThreadSleep (1000);
        if (glIsApplnActive)
        {
            CyU3PDebugPrint (2, "USB Debug logger: time from start in ticks: %d\n", CyU3PGetTime ());
        }
        CyU3PDebugPrint (2, "USB Debug Hello: %d\n", CyU3PGetTime ());
    }
}
到這邊應該就可以在 PC 上看到 debug message 了, 不過, 還有一些地方要注意  

Note

1. FX3 的 Uart 不會立刻顯示. 大約要幾秒鐘之後, PC 上才會開始看到字. 並不是 delay, 而是 Uart 要過幾秒鐘才有作用. 2. 文字偏移, 沒有回到左邊界. 如果 PC 的軟體沒有自動把“\n” 取代成 “\r\n” 就會造成文字一直偏移. 這時可以自己加. 例如 :
CyU3PDebugPrint (2, "USB Debug Hello: %d\n", CyU3PGetTime ());
改成
CyU3PDebugPrint (2, "USB Debug Hello: %d\r\n", CyU3PGetTime ());



















2014年5月4日 星期日

[SPI] Serial Peripheral Interface

 

簡介:

SPI 是 Motorola 所定義的, 一種 4 線同步傳輸協定. 它由一個主控端 (Master), 及多個被控端 (Slave)所構成. 下圖是一個主控端對一個被控端的示意圖.

350px-SPI_single_slave_svg

 

Pin Definition:

SPI 定義了 4 條線, 這 4 條線的名稱有時會有差異, 但是實際上是相同的.

名稱 別名 定義 備註
SCLK SCK SPI 動作的 clock Master 控制, Slave 只能接受, 不能改變
MOSI SDI, DI, SI Master Data Output, Slave Data Input Master 傳送資料給 Slave
MISO SDO, DO,SO Master Data Input, Slave Data Output Slave 傳送資料給 Master
SS nCS, CS, nSS Slave Select Master 選擇被控端時, 將對應的 device 的 select pin 拉 low, 並且使 device 進行 reset. 通常是 GPIO.

SPI 定義了 4 條線, 這 4 條線的名稱有時會有差異, 但是實際上是相同的.

理論上, 把 Slave 的輸出, 連接到另一個 Slave 的輸入, 那麼, 就可以同時和多數個 device 溝通. 不過, 實務上是很少看到這樣的應用.

 

Data Transaction Details:

在下圖中, Master 及 Slave 各有一個 8 bit 的 shift register. 當 Master 對 Slave 做 select 之後 (連接到該 slave 的 SS 拉 low), Master 開始送出 clock, 同時, Master 的資料 ( MSB, 最高位元), 也由 shift register 推到 D 型正反器, 以在 MOSI 上維持住它的值. 需要注意的是, Slave 的資料, 也是在同一時間送到 MISO. 這說明了 SPI 是一個全雙工同步的訊號系統.

在資料送出來的時間點, 和資料被讀取的時間點, 並沒有明確的定義. 因此, 在使用 SPI 介面時, 必需注意 device ( Slave) 所支援的 clock mode.

image

 

Clock modes:

 

Clock modes (SPI-modes) CPOL CPHA  
0 0 0 CPOL =0, 表示 clock 原本在 low. CPHA =0 表示資料在第1個 edge 被讀取.  也就是 rising edge 被讀取
1 0 1 CPOL =0, 表示 clock 原本在 low. CPHA =1 表示資料在第2個 edge 被讀取. 也就是 falling edge 被讀取
2 1 0 CPOL =1, 表示 clock 原本在 high. CPHA =0 表示資料在第1個 edge 被讀取. 也就是 falling edge 被讀取
3 1 1 CPOL =1, 表示 clock 原本在 high. CPHA =1 表示資料在第2個 edge 被讀取. 也就是 rising edge 被讀取

參考以下 Timing chart 可以更清楚瞭解

spi-modes

2014年4月29日 星期二

[Windows Driver Installation] Roadmap for Device and Driver Installation

 

以下說明製作 Windows Vista 及後續版本 Driver Installation 的 8 個步驟

參考連結

http://msdn.microsoft.com/en-us/library/windows/hardware/ff550690(v=vs.85).aspx

Step 1: Learn the fundamentals of device and driver installation in Windows.

你必須了解在 Windows系列, 安裝設備和驅動程序的基礎知識. 這將有助於你做出相應的設計決策, 並簡化開發過程.

參考資料, 設備和驅動程式安裝概述.

Step 2: Learn about driver packages and their components.

驅動程式包中包含所有你必須提供的安裝及支持您的設備的組件. 要安裝一個設備或驅動程序, 您必須擁有系統提供的和供應商提供的組件. 系統提供適用於所有設備的通用安裝軟體. 供應商則在驅​​動程序包中提供一個或多個設備特定的組件.

參考資料, 驅動程式包.

Step 3: Learn about information (INF) files.

INF文件中包含了系統所提供的設備安裝組件, 以安裝你的驅動程式包的資訊和設備設定. 例如設備的驅動程式及搭配設備的軟體.

參考資料, INF 檔案.

Step 4: Learn about additional software installation components.

您的驅動程序包可以包含各種軟體組件, 如輔助安裝程序或類別安裝程序, 可以增強和擴展設備和驅動程序的安裝. 舉例來說, 一個輔助安裝程序可以執行以下操作:

  • 執行 INF 文件無法處理的額外設備安裝任務. 例如, 輔助安裝程序可以寫入額外的設備的特定訊息到 registry.
  • 提供安裝完成嚮導頁面, 以在安裝您的設備後, 顯示額外的嚮導頁面給使用者.
  • 提供完成安裝的動作來啟動其他只能在使用者互動的狀態下執行的安裝程序.

參考資料, 設備和驅動程式軟體安裝.

Step 5: Create a driver package for your device and drivers.

您的驅動程序包必須提供一個INF檔案, 該設備的驅動程序檔案, 以及選擇性的額外軟體. 你可以參考樣本烤麵包機驅動程序包的例子, 以確定哪些是驅動程序包需要的組件.

有關驅動程序包的組件的詳細信息, 請參閱創建驅動程序包 .

有關驅動程序包的更多信息, 請參閱烤麵包機範例.

Step 6: Test-sign your driver package during developemnt and testing.

測試簽名是指, 在測試電腦上, 使用測試認證來簽署預先發布的的驅動程序包. 尤其, 這提供開發人員使用自簽名的證書, 來簽署驅動程序包. 例如, 用 MakeCert 來產生認證的證書. 此功能可以讓開發人員在啟動驅動程式簽署認證的 Window 系統中, 安裝和測試驅動程序.

參考資料, 設備和驅動程式安裝概述: 在開發和測試過程中簽署驅動程序 .

Step 7: Release-sign your driver package for distribution.

當你完成測試並驗證您的驅動程序包, 你應該發行認證你的驅動程序包. 發行認證可以識別驅動程序包的發行者. 雖然這一步是可以選的, 驅動程序包應該作發行認證, 原因如下:

  • 確保真實性, 完整性, 以及驅動程序包的可靠性. Windows使用數位簽名來驗證發行者的身份, 並確認該驅動程序沒有被修改, 因為它被出版了.
  • 通過便利的自動安裝驅動程序提供最佳的用戶體驗。
  • 在在64位版本的Windows Vista和更高版本的Windows 的系統上, 運行核心模式驅動程序。
  • 播放某些類型的新一代優質內容。

驅動程序包可以通過任一方式發行簽名:

參考資料, 為公開發行進行驅動程序簽名.

Step 8: Distribute your driver package.

最後一步是發送 如果你的驅動程序包通過 HCK 定義的認證程序, 就可以透過微軟Windows更新程序發布.

參考資料, 發布驅動程式包.

2014年4月27日 星期日

[Google 翻譯 Bug]

 

發現一個 Google 翻譯的 bug. 但是找不到可以 report bug 的地方. 就先寫在這裡囉.

在翻譯以下連結的時候, 出現一個錯誤.

http://www.beyondlogic.org/usbnutshell/usb4.shtml#Interrupt

原文應該是

As a result Bulk transfers should only be used for time insensitive communication as there is no guarantee of latency.

 

翻譯的結果是:

因此批量傳輸應該只用於時間敏感的通信,因為沒有保證的延遲。

 

如果只翻譯 time insensitive, 結果是 “時間不敏感”, 這是對的. 這應該算是 bug 吧.

 

Google Translator Bug

[EZ-USB FX3] USB Transfer modes


不僅僅是 FX3, 所有的 USB device 都可以有 4 種不同的傳輸模式. 這 4 種不同的傳輸模式, 各自有各自的定位和特性,傳輸速度. 在評估 FX3 的傳輸速度前, 先簡單說明這幾個不同的傳輸模式.
參考連結:
http://www.beyondlogic.org/usbnutshell/usb4.shtml#Interrupt
Control Transfer 控制傳輸
Interrupt Transfer 中斷傳輸
Isochronous Transfer 同步傳輸
Bulk Transfer 大量傳輸

 

Control Transfer: 控制傳輸

定位:
Control Transfer 是被設計作為 USB Host 向 USB Device 下達命令及狀態查詢. 它的作用主要是在於和應用無關的 USB 系統控制. 所以, 每個 device 都必需至少提供一組 Control Transfer 來對應.
當然, 要自己定義一組 Control Transfer 來使用也是可以的.
特徵:
由於是對應 USB Host 的命令, 所以對 device 來說, Control Transfer 是突如其來, 但是它又必需以最高優先權傳送, 所以它可以傳送的資料限制也最大. 通常, 它只能傳送 8/16/32/64 個 bytes 的資料.

Interrupt Transfer: 中斷傳輸

定位:
相對於 Control Transfer 是被動的和 USB Host 溝通, Interrupt Transfer 是被設計作為USB device 向 USB Host 傳送非週期的資料. 但是在 USB 的架構下, 傳輸的頻寬是由 USB Host 分配, 因此, Interrupt Transfer 實際上是先向 USB Host 發出頻寬分配的請求, 然後在下一次傳輸時, 才真正的傳遞資料.
特徵:
Interrupt Transfer 傳送的是非週期性的資料, 這代表這資料的重要性比較高. 因此, Interrupt Transfer 傳送的資料, 可以被保證在一段時間內送達, 而且, 如果傳送錯誤, 它可以在下一個 Host/Device 交換資料的時間內重傳.
Guaranteed Latency
Stream Pipe - Unidirectional
Error detection and next period retry

Isochronous Transfer: 同步傳輸

定位:
同步傳輸用來傳送連續, 定期發生, 對時間敏感的資料. 譬如說, 電話/即時影像/視訊電話等應用. 當中間有一小段資料失誤, 對應用來說, 影響不大, 可能只是很短的一個雜音, 或是畫面破損了一下, 停滯了一下. 由於下一個時間點的資料還是會繼續收到, 因此, 這樣的影響是可以被接受的.
Isochronous Transfer 的資料, 及時送達比資料的正確性重要.
特徵:
Isochronous Transfer 保證在傳輸的過程中, 在每一次傳輸時, 保留預先分配的資料頻寬來傳送資料. 因此, 它可以保證在固定時間內傳輸, 它檢查錯誤, 但是不重傳, 也不保證送達.
Guaranteed access to USB bandwidth
Bounded latency
Stream Pipe - Unidirectional
Error detection via CRC, but no retry or guarantee of delivery
Full & high speed modes only
No data toggling

Bulk Transfer: 大量傳輸

定位:
Bulk Transfer 用來傳送大量突發性, 時間不敏感的資料. 例如外接硬碟, 從 scanner/DSC 接收影像資料. 這些資料, 傳輸錯誤不能容許, 但是慢個一秒也沒有太大的關係. 
Bulk Transfer 的時間優先權是最低的, 因此, 在其他 Transfer mode 作用的情況下, 會延遲較長的時間, 資料才能被送出. 但是在傳輸的頻寬分配完之後, Bulk Transfer 又可以吃光所有剩下的頻寬. 因此, 它又具備最大傳輸能力的可能性.
特徵:
Bulk Transfer 的時間優先權是最低的, 因此, 在其他 Transfer mode 作用的情況下, 會延遲較長的時間, 資料才能被送出. 但是在傳輸的頻寬分配完之後, Bulk Transfer 又可以吃光所有剩下的頻寬. 因此, 它又具備最大傳輸能力的可能性.
Used to transfer large bursty data
Error detection via CRC, with guarantee of delivery
No guarantee of bandwidth or minimum latency
Stream Pipe-Unidirectional
Full & high speed modes only