CYPEESS USB3.0程式解讀之---GPIO
CPRESS 官方給出的SDK1.1中(目前最新的SDK),提供了大量的例程供我們開發軟體的時候作參考,就像STM32的開發一樣提供了庫一樣,但是又不是庫,僅僅是參考例程。
首先看一個簡單一點的GPIO的例子(GpioApp)
1.先是一個錯誤處理的函式,我們不需要它,故這是一個死迴圈。
2. CyFxDebugInit 這個函式,將串列埠作為除錯口用115200bps。
3.
void CyFxGpioIntrCb (
uint8_t gpioId /* Indicates thepin that triggered the interrupt */
)
這個函式是一箇中斷回撥函式。必須在某個地方註冊一下。
它有下列過程:
apiRetStatus=CyU3PGpioGetValue(gpioID,&gpioValue);
這個函式得到某個埠中斷的值這個gpioValue是一個BOOL值。而ID則是某一個埠的埠號。這個函式只能返回一個引腳。
下面介紹這個ID是什麼指定的。
4.
CyU3PEventSet(&glFxGpioAppEvent,CY_FX_GPIOAPP_GPIO_HIGH_EVENT,CYU3P_EVENT_OR);
如果為高,則設定一個事件。是一個高事件發生。注意到事件是一個全域性變數,而這個事件中有許多引數,其中比較重要的是一個回撥函式。應該在某個地方將這個事件與一個回撥函式聯絡起來。
5.voidCyFxGpioInit (void)
apiRetStatus =CyU3PGpioInit(&gpioClock,CyFxGpioIntrCB);
這個函式是設定gpio的時鐘,以及中斷的回撥函式。這與4中部分形成對照。
然後將gpio45定義為輸入且允許中斷
gpioConfig.intrMode = CY_U3P_GPIO_INTR_BOTH_EDGE;
apiRetStatus = CyU3PGpioSetSimpleConfig(45, &gpioConfig);
GPIO的21指令碼來作為GPIF的控制訊號的。不能用CyU3PDeviceConfigureIOMatrix來將它作為GPIF IOs.
這個過載API呼叫必須進行必須小心當改變這個引腳的功能時。如果IO腳作為GPIF的一部分連到外部裝置上。則它不能再作為GPIF IO使用。在這裡CTL4是不使用的,所以用它用IO腳是安全的。
apiRetStatus = CyU3PDeviceGpioOverride(21,CyTrue);
接下來
apiRetStatus =CyU3PGpioSetSimpleConfig(21,&gpioConfig);
6. 接下來有兩個執行緒,一個是輸出執行緒,一個是輸入執行緒,先看輸出執行緒:
apiRetStatus = CyFxDebugInit();
初始化除錯模式。這個在2中定義的。CyFxGpioInit();
這個也在前面定義過。後面是一個閃燈程式。apiRetStatus = CyU3PGpioSetValue(21,true);
將輸出置為高。延時2秒,將輸出變為低。
延時2秒。
7. 下面再來看輸入執行緒:是一個迴圈,等事件發生。
txApiRetStatus = CyU3PEventGet(&glFxGpioAppEvent,
(CY_FX_GPIOAPP_GPIO_HIGH_EVENT |CY_FX_GPIOAPP_GPIO_LOW_EVENT),
CYU3P_EVENT_OR_CLEAR,&eventFlag, CYU3P_WAIT_FOREVER);
這裡表示永遠等下去。等到後要清除事件,另返回事件的標誌,這個標誌我們沒有用。如果等到高的標誌,就列印一個引腳為高,如果為低,就列印一個引腳為低的標誌。估計這個等事件標誌將被block.
這樣整個過程清楚了,IO腳觸發引起一箇中斷。這個中斷回撥函式中將觸發一個事件。在這個執行緒中將等事件發生,如果發生了,就打印出引腳的狀態。
事件在什麼地方初始化呢?還是不需要初始化?
8. 事件是要初始化的。在應用程式中初始化了,下面就看這個應用程式
先建立一個輸出執行緒。
再建立一個輸入執行緒
然後
retThrdCreate =CyU3EventCreate(&glFxGpioAppEvent);
9. 最後看一下main()
main()中主要是將GPIO引腳初始化一下。
io_cfg.gpioSimpleEn[0] = 0;
io_cfg.gpioSimpleEn[1] = 0x00002000; /* GPIO 45 */
io_cfg.gpioComplexEn[0] = 0;
io_cfg.gpioComplexEn[1] = 0;
45引腳為什麼對應的是0x2000.?這是因為它是32位的,45引腳=32+13 ,這個第13位正好是0X2000(1<<13 就是0x2000)。
*例項總結
從main開始看起:
再看一下幾個定義:輸出執行緒,輸入執行緒及事件在檔案一開始就定義了。
CyU3PThread gpioOutputThread; /* GPIOthread structure */
CyU3PThreadgpioInputThread; /* GPIO thread structure */
CyU3PEventglFxGpioAppEvent; /* GPIO input event group. */
它主要是呼叫了一個串列埠設定函式,然後就進入到cache控制設定,再後來就是設定一個IO腳,45腳使之使能。並且選用配置模式(即LPP模式)。允許了UART,不允許IIC,IIS,SPI,另外isDQ32bit也不允許。這個表示它不支援GPIF的32位模式。
然後我們再看應用程式啟動,這是由系統自動呼叫的。我們可能修改它的內容,但是它是必須的。
這個函式中,它建立了兩個執行緒。一個是輸入執行緒,一個是輸出執行緒。
另外,容易遺忘的一件事是它建立了一個事件。事件的建立只要這樣就可以了:
retThrdCreate = Cy3U3PEventCreate(&glFxGpioAppEvent);
再往上,就是輸入執行緒了。這個執行緒看輸入引腳的變化,而這個變化由中斷回撥函式引起,中斷回撥函式中,它會產生一個事件,而我們的執行緒就監視這個事件。如果有事件高發生,就串列埠列印一個引腳高,如果低,就列印一個引腳低。看它是如何實現的:
txApiRetStatus =CyU3PEventGet(&glFxGpioAppEvent,
(CY_FX_GPIOAPPP_GPIO_HIGH_EVENT|CY_FX_GPIOAPP_GPIO_LOW_EVENT),
CYU3P_EVENT_OR_CLEAR,&eventFlag,CYU3P_WAIT_FOREVER);
這是個等事件的函式,這個函式無法找到它的定義,它是一個API函式。我們找API,發現它的引數含義。
這裡有一個CYU3P_EVENT_OR_CLEAR表示只要上面有一個位被設定就返回且清除標誌。----OR。
而真正的事件就放在標誌中返回了。
既然有讀事件,就必有設定事件,事件的設定應該在中斷回撥中實現。而中斷回撥的註冊,應該在初始化時實現。下面應該可以很快看到這點。---事實上,在下面的輸出執行緒中就實現了註冊。
輸出執行緒實現,輸出執行緒比較有意思的是其DebugInit()居然是在它中間實現的,其實這個也可以在main中。
而接下來,它又呼叫了初始化GpioInit()這個函式。在這個函式中,先初始化GPIO,這個GPIO居然還要將時鐘也設定一下,有點不合常理。在這個初始化中,它還指明瞭GPIO中斷回撥函式的註冊。儘管這個中斷函式應該是在輸入執行緒中註冊似更合理一些。接下來,45腳要用之為輸入,所以要將配置設一下:
gpioConfig.outValue = CyTrue; //輸出為高 因為是輸入,要將它設為高
gpioConfig.inputEn = CyTrue; //輸入使能
gpioConfig.driveLowEn = CyFalse; //不要驅動低也不要驅動高
gpioConfig.driveHighEn = CyFalse;
gpioConfig.intrMode = CY_U3P_GPIO_INTR_BOTH_EDGE; //允許中斷
apiRetStatus = CyU3PGpioSetSimpleConfig(45, &gpioConfig);
如此這般配置了45腳。
接下來,要配置21腳,因為21腳比較特殊本來是用於GPIF的CTRL4的。現在要使用它就要過載一下:
這樣的IO腳是不可以象在主程式中哪樣,將它直接設為輸出的,而是要先過載。
同樣,看輸出腳是如何定義的
gpioConfig.outValue = CyFalse; //低電平
gpioConfig.driveLowEn = CyTrue; //允許低輸出
gpioConfig.driveHighEn = CyTrue; //允許高輸出
gpioConfig.inputEn = CyFalse; //方向設為輸出
gpioConfig.intrMode = CY_U3P_GPIO_NO_INTR; //不用中斷
再看一下回調函式,如何實現它的:
當引腳有跳變時,這個函式被呼叫。首先,它得到引腳的值。這個回撥函式是帶引數的。當它發生時,會帶過來一個引數。表明是哪一個引腳觸發了這個事件。這在庫函式中可能已經處理了,提供給使用者程式就不用麻煩再去看原因了。我想可能有一個機制,即有一箇中斷狀態暫存器,表示是哪一個引腳變化了。
在這裡呼叫了一個函式:
CyU3PGpioGetValue(gpioId,&gpioValue);
注意到這個值是一個BOOL型的。
然後根據情況來設定事件:
CyU3PEventSet(&glFxGpioAppEvent,CY_FX_GPIOAPP_GPIO_HIGH_EVENT,CYU3P_EVENT_OR);
我們看,其中有要設定的事件指標,有什麼事件,以什麼方式設定,它是以OR的方式設定的。這個OR表示的是將這個第2個引數與當前的事件標誌進行或。顯然,如果相或的話,則事件標誌將被置1,而如果與則完全不同,它沒效果。(在得到事件中,有一個AND表示全部標誌都符合才生成事件,所以也是用OR的,不然,不可能全部符合的,永遠不會發生事件了,因為不可能既變高又變低的)。
至此整個程式解讀完了。在這個例子中,沒用到USB有關的部分。就是當一個MCU用的GPIO,因為這個晶片的CPU是ARM926EJ的核心,執行頻率可以達到200MHz,和之前的FX2晶片的51核心完全不是一個級別,所以這個做主控晶片是完全可以的。相關推薦
CYPEESS USB3.0程式解讀之---GPIO
CPRESS 官方給出的SDK1.1中(目前最新的SDK),提供了大量的例程供我們開發軟體的時候作參考,就像STM32的開發一樣提供了庫一樣,但是又不是庫,僅僅是參考例程。首先看一個簡單一點的GPIO的例子(GpioApp)1.先是一個錯誤處理的函式,我們不需要它,故這是一個
CYPEESS USB3.0程式解讀之---SPI讀寫
前面已經解讀了GPIO以及同步FIFO操作,下面我們看一個SPI讀寫的例子,它是主程式命令從SPI中讀寫一些資料。SPI傳輸子程式看一下: 頁地址,位元組計數,緩衝區,讀寫標誌因為只能一頁一頁的讀或寫,故讀寫總是從頁地址開始的/* SPI read / writefor pr
Android6.0原始碼解讀之Activity點選事件分發機制
本篇博文是Android點選事件分發機制系列博文的第四篇,主要是從解讀Activity類的原始碼入手,根據原始碼理清Activity點選事件分發原理,並掌握Activity點選事件分法機制。特別宣告的是,本原始碼解讀是基於最新的Android6.0版本。
深入解讀HBase2.0新功能之高可用讀Region Replica
數據庫摘要: 基於時間線一致的高可用讀(Timeline-consistent High Available Reads),又稱Region replica,為HBase帶來了高可用讀的能力。本文主要介紹region replica這個功能設計的背景,技術細節和使用方法,同時會仔細分析這個功能的優缺點並給出使
從0開始的web程式猿之路
寫寫自己剛入程式設計師,然後又走向JAVA,web短短一年的經驗和經歷,寫給未來自己,也寫給迷茫的新人們,讓他們少走一點彎路。 剛開始,學了c,就想做東西,現實狠狠的告訴我,發現只學了c做不了什麼
5.0 SpringBoot普通上傳功能 > 我的程式猿之路:第四十章
SpringBoot 2.0 1.upLoad.html 1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta ch
5.0 SpringBoot普通上傳功能 > 我的程式猿之路:第四十章
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8"> 5 <title
USB3.0 之 RX Detect 的基本原理
RX Detect 的基本原理 在USB3.0 中 Device 連線到 Host等價於連線了一個R_Term 左圖為不接device的等效電路,此時由於R_term不存在,故電路模型實際為一RC串聯電路,可簡單計算出時間因子: T=R_DetectC_Parasitic, 右圖為接上de
深入解讀 HBase2.0 新功能之高可用讀 Region Replica
1.前言 基於時間線一致的高可用讀(Timeline-consistent High Available Reads),又稱 Region replica。其實早在 HBase-1.2 版本的時候,這個功能就已經開發完畢了, 但是還是不太穩定,離生產可用級別還有一段距離,後來社群又陸陸續續修復了 一些 bu
USB3.0 HDMI輸入方案之FT601Q
USB3.0 HDMI輸入方案之FT601Q &nb
vue2.0學習筆記之webpack-simple模板中的路由簡單配置案例
nbsp 主頁 default code vue 兩個文件 new ebp 命名 以下是完成後的目錄結構 案例基礎是已經用 webpack+vue-cli 創建了一個名為 vue_router的工程 , 並安裝了vue-rout
vue2.0學習筆記之自定義組件
2.0 sco ron 自定義組件 定義 temp use 使用 imp step one: 推薦結構 step two: Loading.vue <template> <h3>{{msg}}<
win 7 旗艦版鏡像 註入USB3.0 驅動
win 7 旗艦版鏡像 註入usb3.0 驅動問題來源:原版的win7鏡像沒有集成USB3.0的驅動,然後如今的電腦主板基本是XHCI主控(以前是EHCI的),這一變動導致在安裝Win7的過程中會出現USB接口全部失靈的狀況,所以在安裝時無法識別USB3.0接口的鍵盤鼠標和U盤。這樣我們就只能在映像文件中添加
Android5.0網絡之ipv6
ipv6地址 自己的 mod 大量 路由 ng- and 問題 ati 移動設備的大量興起勢必進一步加強ip地址不足的危機。ipv6或許成為一種比較好的選擇方案。 ipv6地址的獲取分為兩種方式:無狀態;有狀態 無狀態:通過接收路由公告(RA)來設置自己的ipv
dell usb3.0驅動故障
usb 驅動 dell 一、故障現象 dell3046 dell3050新主機安裝操作系統時,在BIOS、pe中能夠正常使用USB鍵鼠,安裝成功後,進入windows登錄後,安全模式,USB鍵鼠無任何反應。二、處理過程 1.因使用wds安裝系統,首先錯誤的認為是wds本身的問題,嘗試在WD
JDK 源碼解讀之 Number類
only ria method key tty str can pre ati public abstract class Number implements java.io.Serializable { Number類有修飾符 abstract 。表明Numbe
C語言在linux內核中do while(0)妙用之法
pos turn jsb world div fprintf cpp efault code 為什麽說do while(0) 妙?由於它的確就是妙,並且在linux內核中實現是相當的妙,我們來看看內核中的相關代碼: #define db_error(fmt, ..
JDK 源碼解讀之 ArrayList
ont xtend empty 文檔 code access extend ces doesn public class ArrayList<E> extends AbstractList<E> implements List&l
Angular4.0踩坑之路:探索子路由和懶加載
ati clas per 而是 配置 trap child property one 參考文章: Angular4路由快速入門 http://www.jianshu.com/p/e72c79c6968e Angular2文檔學習的知識點摘要——Angular模塊(NgMo
.NET Core 2.0遷移技巧之MemoryCache問題修復
命名空間 ram ons ret http option ext obj mar 對於傳統的.NET Framework項目而言,System.Runtime.Caching命名空間是常用的工具了,其中MemoryCache類則常被用於實現內存緩存。 .NET Core