2013年12月27日 星期五

Beaglebone Black I/O library 開發歷程(三) - GPIO module


How to access GPIO using mamp in TI AM335x CPU

Base on Beaglebone Black

C Library development note


Author : Cai , Meng-Lun , (VegetableAvenger) , 2013/12/19

Introduction :

這份筆記的內容正式涵蓋了BBBio library的內容,這份文件將介紹如何再Beaglebone black上利用C語言與mmap來進行GPIO的操作,以user space的方式來控制硬體,而不用去撰寫專用的Device Driver,同時粗略的介紹一下AM335xSystem Interconnect架構,以瞭解module的布局方式以及Clock manager的管理,最後將演示一段透過BBBio library,使用按鈕開關來控制LED閃爍速度的程式碼。


This note contain :
  • AM335x System Interconnect Architecture
  •  AM335x GPIO module introduction
  •  Memory map of AM335x GPIO module
  •  Enable/Disable Clock of GPIO module via CM_PER/CM_WKUP register
  •  GPIO register
  •  Get BBBio
  •  LED Demo

部份文字內容或圖片 reference from : AM335x Technical Reference Manual


AM335x System Interconnect Architecture :

AM335xinterconnect Architecture 2-Level架構,由L3L4組成,而L3則分為L3FL3S,而L4則是分為L4_FASTL4_PERL4_WKUP,結構如圖1所示,由其可看出L4_PERL4_WKUP是掛接在L3_S下,而L4_FAST則是接在L3F下。





1L3 Topology (AM335x TRM page 1231)

GPIO模組則是分佈在L4之中,GPIO 0掛在L4_WKUPGPIO 1~3掛在L4_PER中,整體上如圖2所示。




2L4 Topology (AM335x TRM page 1234)


瞭解GPIO模組所屬的Interconnect Topology有助於瞭解各module間的Clock互動情形,即瞭解module所屬的Clock Domain,像是GPIO 1~3所處的Clock DomainPD_PER_L4LS_GCLK,而GPIO 0 則處在PD_WKUP_L4_WKUP_GCLK這個Clock domain上,而透過圖2L4 Topology布局方式便可以清楚的瞭解為何GPIO模組會處於不同的Clock Domain上。

為了要讓module省電,所以沒有必要使用的moduleClock常處於Disable的狀態,而每一個GPIO模組擁有其各自的register來控制是否Disable Clock,瞭解其Clock domain之後,便可以搜尋其對應的Clock control register,接著才可以在需要使用時,將GPIOClock Enable/Disable,下表為各GPIOClock control register




GPIO

Clock Domain

Speed

Clock Control Register

GPIO 0

PD_WKUP_L4_WKUP_GCLK

100M Hz

CM_WKUP_GPIO0_CLKCTRL

GPIO 1

PD_PER_L4LS_GCLK

100M Hz

CM_PER_GPIO1_CLKCTRL

GPIO 2

PD_PER_L4LS_GCLK

100M Hz

CM_PER_GPIO2_CLKCTRL

GPIO 3

PD_PER_L4LS_GCLK

100M Hz

CM_PER_GPIO3_CLKCTRL

1GPIO Clock Domain

AM335x GPIO Module Introduction :

AM335x 擁有4GPIO moduleGPIO 0GPIO 1GPIO 2GPIO 3,每一個module32支接腳,故總共有128GPIO的腳位可以使用,每支腳位提供以下的基本功能:
  1. Data Input/ Output
  2. Debounce cell
  3. Synchronous interrupt
  4. Wake-up request (Only GPIO 0)

本筆記主要記錄最基本的Data Input/OutputDebouncing為次章節介紹,而剩餘功能尚未完整測試。

基本上每一組GPIO都提供了1~3的基本功能,而GPIO 0 則額外提供了Wake-Pp的功能,是與其他GPIO較為不同的地方,如圖3所示,可以發現GPIO 0的模組配置較GPIO 1~3不同,而圖中各GPIO modulePIDBCLK則為Debouncing Clock的輸入訊號,而POINTRPEND1 /2則是用來產生interrupt的訊號。

 


3GPIO0~3 Module Integeration (AM335x TRM page 4630)

由圖3可知,GPIO模組操作起來所需要的條件並沒有很多,若是不考慮wake up功能的話,基本上GPIO 0~3功能是一樣的,只需要注意在L4 WakeUP InterconnectL4 Peripgeral InterconnectClock有輸入進GPIO模組,接著只要在GPIO module相對應的register之中進行操作,即可控制pin腳的狀態。


Memory map of AM335x GPIO module

接著從AM335x之中,查出GPIO對應的Memory Map的位址,以利用mmap進行存取動作

AM335x TRMpage .171Table 2-2. L4_WKUP Peripheral Memory Map

AM335x TRMpage .173~174Table 2-3. L4_PER Peripheral Memory Map



Region Name

Start Address

End Address

Size

Description

CM_PER

0x44E0_0000

0x44E0_3FFF

0x4000

Clock Module Peripheral Registers

CM_WKUP

0x44E0_0400

0x44E0_04FF

0x100

Clock Module Wakeup Registers

GPIO0

0x44E0_7000

0x44E0_7FFF

0x1000

GPIO register

GPIO1

0x4804_C000

0x4804_CFFF

0x1000

GPIO2

0x481A_C000

0x481A_CFFFF

0x1000

GPIO3

0x481A_E000

0x481A_EFFFF

0x1000

2GPIO Memory map
 

Enable/Disable Clock of GPIO module via CM_PER/CM_WKUP register

Clock上要特別注意,由先前提過的表1可知,GPIO 0 屬於PD_WKUP_L4_WKUP_GCLKClock domain,控制RegisterCM_WKUP_GPIO0_CLKCTRL,而GPIO 1~3屬於PD_PER_L4LS_GCLKClock domain,控制RegisterCM_PER_GPIOx_CLKCTRL (x1~3),要小心不要控制錯了,名字是有差別的。

GPIO模組基本上會有2Clock的輸入:Interface ClockDebouncing ClockInterface ClockL4 Iterface提供,100MHz的頻率,而Debouncing Clock則是可選的(不需要就Disable沒關係),為32.768KHz,如果interface clock 沒有Enable,那整組GPIOregister access 都會error,並回傳Bus Error的選項。

瞭解要控制的Register之後,接著就是去看他的格式,相對應的頁數列於表3,而基本上這4reigister的控制參數格式是一模一樣的,如圖4所示,因此我們只需要將Bit 0~1MODULEMODE欄位設為0x2 (Enable)即可打開相對應GPIOClock




Register Name

Page

Session

CM_WKUP_GPIO0_CLKCTRL

983

Session 8.1.12.2.3

CM_PER_GPIO1_CLKCTRL

947

Session 8.1.12.1.29

CM_PER_GPIO2_CLKCTRL

948

Session 8.1.12.1.30

CM_PER_GPIO3_CLKCTRL

949

Session 8.1.12.1.31

3GPIO Clock Register page Reference
 

而這裡有一個需要注意的欄位,OPTFCLKEN_GPIO_x_GDBCLK (bit 18),這個欄位是用來Enable/Disable Debouncing Clock的,即圖3PIDBCLK



4GPIO Clock Register format
 

mmap程式碼:

BBBio/BBBio.ciolib_init fnuction之中,需要map 2+4map,分別是控制Clokc的:CM_PERCM_WKUP,和GPIO moduleGPIO0~3

其中需要特別注意CM_WKUP,其memory map位址為0x44E0_0400,這個位址直接下去mmap,會回傳error,同時error code為:EINVAL,這是因為0x44E0_0400這個address並沒有alignment page,這裡的page4K,所以mmap沒有辦法map;不過這是可以處理的,在BBBio中,先mmap CM_PER (0x44E0_0000)這個register,在透過offset 0x400,存取CM_WKUP,即可mmap CM_WKUP,因為在mmap CM_PER時,其maplength已經涵蓋了CM_WKUP



cm_per_addr = mmap(忽略参數) ;

cm_wkup_addr =(void *)cm_per_addr + 0x400 ;

Enable/Disable程式碼:

BBBio/BBBio.cBBBIO_sys_Enable_GPIOBBBIO_sys_Disable_GPIO fnuction之中,
 

GPIO register

GPIO module基本上需要:InputOutputI/O方向設定,3個功能,而AM335xGPIO module則是將這些功能透過以下register控制



Action

Register Name

Offset

I/O Setting

GPIO_OE

0x134

Input

GPIO_DATAIN

0x138

Output

GPIO_CLEARDATAOUT

GPIO_SETDATAOUT

GPIO_DATAOUT

0x190

0x194

0x13C

4GPIO Control Register

I/O Setting

透過GPIO_OE register來控制PIN腳是要Inpout還是Output,一次設定整組的GPIO I/O status,共32bit,每一個bit對應1個腳位,bit設為0代表output,設為1代表Input

例如:GPIO 0GPIO_OE register bit 0代表 GPIO 0 [0]這支pin腳,若是寫入0x00000001,代表將pin0腳位設為input,其他設為output

請特別注意:建議透過邏輯運算| (or),來進行操作,因為有些GPIO不是你可以亂動的,以Beaglebone black來說,其外部接角插槽只有96pin,而且有些pin不是GPIO,代表不是每一個GPIO都有拉出去,若是你亂改到非外拉的腳位狀態,或許會造成系統/裝置錯誤,因此,設定數值前請三思並檢查。

 Input Setting

透過GPIO_DATAIN來取得PIN腳目前輸入的狀態,一次讀入整組的GPIO input status,共32bit,每一個bit對應1個腳位,例如GPIO 0GPIO_DATAIN register bit 0代表 GPIO 0 [0]這支pin腳,因此讀出GPIO_DATAIN的數值之後,你需要自己利用邏輯運算& (and),來判斷需要的腳位狀態。

Output Setting

Output的設定就比較有趣了,這裡我將他分成2種操作模式:獨立控制直接控制

 獨立控制代表一次操作下,只可以控制腳位是輸出0還是1

直接控制代表一次操作下,可以一次控制一整組的GPIO狀態,Pin可為0 也可為1



模式

Register

解說

獨立控制

GPIO_CLEARDATAOUT

GPIO_SETDATAOUT

設定Pin腳輸出0

設定Pin腳輸出1

直接控制

GPIO_DATAOUT

設定GPIO輸出

5GPIO Output Control Register

假設你需要將8LED 同一時間一次點亮,那你可以使用獨立控制或是直接控制,但若是同一時間下,需要點亮4個,滅掉4LED,那就只能使用直接控制的功能,否則你必須使用2次獨立控制的register,先下GPIO_SETDATAOUT 4個,在下GPIO_CLEARDATAOUT指令滅4個。

 獨立控制 寫入方式:

一次寫入代表寫入整組的GPIO Output status,共32bit,每一個bit對應1個腳位;要讓某pin腳設為1則在GPIO_SETDATAOUT相對應的bit寫入1,要設為0,則在GPIO_CLEARDATAOUT寫入1,你沒看錯,都是寫入1,因為這2register分別用來進行Output 0Output 1,寫入1代表此PIN腳要進行設定,寫入0則沒有任何效果。

 直接控制 寫入方式:

直接控制的寫入方式就很直覺了,一樣一次寫入代表寫入整組的GPIO Output status,共32bit,每一個bit對應1個腳位;要某pin腳設為1則在GPIO_DATAOUT相對應的bit寫入1要設為0,則在GPIO_DATAOUT寫入0跟一般的用法無異。

請特別注意:以上運算一樣建議透過邏輯運算| (or),來進行操作,因為有些GPIO不是你可以亂動的,以Beaglebone black來說,其外部接角插槽只有96pin,而且有些pin不是GPIO,代表不是每一個GPIO都有拉出去,若是你亂改到非外拉的腳位狀態,或許會造成系統/裝置錯誤,因此,設定數值前請三思並檢查。


Get BBBio

BBBioShabaz開發,Cai,Meng-Lun維護的Beaglebone black I/O library,為一套自由軟體,任何人可以自由更改,沒有授權問題,目前置放於github :

https://github.com/VegetableAvenger/BBBIOlib

 LED Demo

5為實際範例圖和電路圖,詳細的程式碼請參閱BBBio library中的Demo/Deno_LED_GPIO/




 

5LED Demo & CircuitLayout




6 則留言:

  1. 太棒了!
    台灣竟然有人玩BBB,玩得如此的棒。

    回覆刪除
    回覆
    1. 謝謝,還在摸索階段中,歡迎一起討論!!

      刪除
  2. 我有用了你的lib寫了與DS1302 RTC的讀寫, 若你有需要當library內的sample
    可以給你

    回覆刪除
    回覆
    1. 真是太感謝你了! 不過這個library的license是free software,所以demo的部分也會是free software,不知道你會介意嗎?

      刪除
  3. 不會介意!取之free software,用之於社會free software
    不過...我英文很破! 屆時還要麻煩你的地方還很多
    那要準備哪些東西給你(照片,圖...)

    回覆刪除
    回覆
    1. 可能要麻煩你把source code發給我!
      my email : r7418529@gmail.com

      順便告訴我你用的IC或者是module的型號??
      圖的話....如果你方便的話,可以請你標明一下接腳嗎? 我再把BBBio library的Visio file發給你。

      感謝!

      刪除