作者: 林普賢
( sam91001200@gmail.com
)、 孫文良( iws6645@gmail.com )
首先要去看開發板的電路圖。這裡以Beaglebone green wireless這塊開發板(dev. board)為例,在以下網址可以找到此開發板的電路圖[1]。
https://wiki.seeedstudio.com/BeagleBone_Green_Wireless/
(註: 而我們實驗時所使用的Beaglebone green wireless與Beaglebone Black這兩塊板子上面的系統晶片SoC同為TI的AM3358,所以在此二塊開發板上,其驅動GPIO的方式是同理的。)
如果我們想要點亮開發板上的D5 LED,就必須尋找它連接的引腳。由下圖可以得知D5所連接的引腳為GPIO1_24。
這時候我們就可以在AM335x的Datasheet[2]找到原來GPIO1_24的PIN_Name是GPMC_A8,並且引腳的模式需要選擇為7。
現在我們已經知道要操作的引腳是GPMC_A8,接下來就是看Reference Manual的GPIO feature去了解如何操作各個暫存器完成我們想要的功能。
由上面這張系統框圖可以看到,整個GPIO的操作其實不困難。給GPIO週邊提供時鐘、配置GPIO週邊的I/O方向、最後多工器選擇引腳的輸出由哪個週邊接管。有了這個系統框圖再搭配各個暫存器的說明,要自己寫出GPIO的裝置驅動程式相信不會太困難。
首先是圖中最左邊的Power & Clock,有玩過stm32的朋友一定很熟悉。沒錯,就是打開GPIO週邊的時鐘,沒有這個時鐘GPIO週邊是不會工作的。我們需要驅動LED的引腳是GPIO1_24,所以要操作CM_PER_GPIO1_CLKCTRL這個暫存器將GPIO1的時鐘打開。
操作記憶體地址這邊只講一次,其他暫存器的地址也是這樣查找的。在Reference Manual[3]我們尋找CM_PER_GPIO1_CLKCTRL應該找的到以下資訊:
可以看到CM_PER_GPIO1_CLKCTRL它的記憶體地址是基於CM_PER偏移了AC h,至於CM_PER的地址在哪裡呢? 可以在Memory Map的章節查到:
所以這樣我們就知道了CM_PER_GPIO1_CLKCTRL的記憶體地址,接下來要要看看需要設定這個暫存器的哪些內容。這裡需要操作Bit 18的欄位以及Bit [0:1],表示將時鐘致能開啟GPIO功能。對應的example code(先暫時不討論ioremap)如下:
static volatile unsigned int *CM_PER_GPIO1_CLKCTRL = 0x44E00000 +
0xAC;
*CM_PER_GPIO1_CLKCTRL = (1<<18) | 0x2;
接下來要講解GPIO週邊的暫存器操作,在裝置初始化的時候其實只需要操作GPIO1_OE將output功能啟用就好,而GPIO1_CLEARDATAOUT和GPIO1_SETDATAOUT都是在撰寫功能時才會進行操作。這裡只會講解GPIO_OE的操作方式,其餘兩個暫存器的操作方式也是同理。
可以看到上圖說明想要啟用GPIO1對應接腳需要對相對應的bit進行clear操作,對應的程式如下:
*GPIO1_OE &= ~(1<<24); //
將GPIO1_24設置為輸出模式
*GPIO1_CLEARDATAOUT = (1<<24); //
將GPIO1_24置1(高電位)
*GPIO1_SETDATAOUT = (1<<24); //
將GPIO1_24清 0(低電位)
最後是GPMC_A8的引腳選擇功能。由於晶片的接腳有限,對於同一支引腳它可能被各個不同的週邊共享,但同一時間只能選擇一種功能進行操作。這裡我們需要的選擇一般的輸入輸出模式,所以需要將對應的暫存器賦值為7(先前有提及)。對應的程式如下:
*conf_gpmc_a8 = 7;
至此,所有涉及點燈的GPIO操作以及其對應的暫存器已講解完畢,如果手邊有基於AM335x系列處理器的開發板的朋友,可以趕緊來實戰看看驗證成果。
References:
[1] Seeed Studio BeagleBone® Green Wireless Schematic
[2] AM3358 Datasheet
[3] AM3358 Technical Reference Manual
林普賢、孫文良
-----