前面的兩篇Linux驅(qū)動(dòng)文章
【i.MX6ULL】驅(qū)動(dòng)開發(fā)1--字符設(shè)備開發(fā)模板
【i.MX6ULL】驅(qū)動(dòng)開發(fā)2--新字符設(shè)備開發(fā)模板
介紹了字符設(shè)備驅(qū)動(dòng)的兩種新舊開發(fā)方式,并使用一個(gè)虛擬的字符驅(qū)動(dòng)來學(xué)習(xí)字符設(shè)備的開發(fā)的流程。
本篇起,就要來操作Linux開發(fā)板的硬件,首先當(dāng)然是通過經(jīng)典的點(diǎn)亮LED燈程序,來學(xué)習(xí)Linux IO口操作的字符設(shè)備開發(fā)流程。
對(duì)比STM32的點(diǎn)燈程序,有寄存器操作與庫函數(shù)操作兩種,但其本質(zhì)都是在配置寄存器。
同樣,i.MX6ULL也有多種點(diǎn)燈方式:
裸機(jī)系統(tǒng):匯編操作寄存器點(diǎn)燈、C語言操作寄存器點(diǎn)燈
跑Linux系統(tǒng):字符驅(qū)動(dòng)LED點(diǎn)燈、設(shè)備樹驅(qū)動(dòng)LED點(diǎn)燈
究其本質(zhì),最終都是要操作i.MX6ULL的寄存器。比如,在控制GPIO引腳實(shí)現(xiàn)LED亮滅時(shí),會(huì)進(jìn)行類似如下的寄存器配置:
/* 寄存器物理地址 */
#define CCM_CCGR1_BASE (0X020C406C)
#define SW_MUX_SNVS_TAMPER3_BASE (0X02290014)
#define SW_PAD_SNVS_TAMPER3_BASE (0X02290058)
#define GPIO5_DR_BASE (0X020AC000)
#define GPIO5_GDIR_BASE (0X020AC004)
那這些寄存器都是什么作用呢?這些地址是怎么確定的呢?
所以,在學(xué)習(xí)GPIO控制LED點(diǎn)燈之前,需要先了解清楚有關(guān)GPIO的寄存器配置。
既然是要操作硬件,首先就來看一下i.MX6ULL這個(gè)芯片的IO口基本信息。
1 認(rèn)識(shí)Linux開發(fā)板的GPIO口
首先要明確:IO與GPIO是兩個(gè)概念,GPIO是屬于IO的一部分。
IO: Input Output,用于CPU與外界進(jìn)行信息交互。例如CPU 讀內(nèi)存數(shù)據(jù)需要 I/O 系統(tǒng),CPU 輸出數(shù)據(jù)到屏幕顯示出來也需要 I/O 系統(tǒng),信息在 I/O 系統(tǒng)上傳輸有串行或并行。
GPIO: General-Purpose IO ports,即通用I/O口,在微控制器芯片上一般都會(huì)提供一個(gè)“通用可編程I/O接口”。接口至少有兩個(gè)寄存器——數(shù)據(jù)寄存器與控制寄存器。數(shù)據(jù)寄存器的各位直接引到芯片外部,控制寄存器則是對(duì)數(shù)據(jù)寄存器中每一位進(jìn)行獨(dú)立的設(shè)置。
1.1 板子LED硬件原理圖
在開始介紹i.MX6ULL的GPIO之前,先來看一下板子的原理中對(duì)于LED的標(biāo)注。
我這塊板子(野火EBF6ULL S1 Pro)的原理圖中關(guān)于LED電路的部分,如下圖所示。
這里出現(xiàn)了兩種標(biāo)注:SNVS_TAMPER3與GPIO5_IO03,先對(duì)這兩個(gè)名稱有個(gè)印象,下面就來介紹其含義。
另外,從原理圖可以看出,低電平時(shí)LED燈會(huì)亮起。
1.2 GPIO邏輯結(jié)構(gòu)
下圖為i.MX6ULL的GPIO硬件結(jié)構(gòu)框圖,其中①和⑤的PAD表示i.MX6ULL芯片引出的GPIO引腳,其余部件都位于芯片內(nèi)部。
① PAD:它代表了i.MX6ULL芯片的一個(gè)GPIO引腳。
② IOMUX復(fù)用選擇器:與STM32的引腳復(fù)用功能類似,i.MX6ULL芯片的每個(gè)IO通過IOMUXC中的MUX寄存器和PAD寄存器設(shè)置,可以支持多種功能(如GPIO、IIC、USART...)。
③ Block外設(shè)功能控制塊:例如具有PWM輸出功能的引腳,它需要PWM外設(shè)的支持。
④ GPIO外設(shè):GPIO模塊是每個(gè)IO都具有的外設(shè), 它是IO控制的基本功能, 如輸出高低電平、 檢測(cè)電平輸入等。當(dāng)需要使用引腳的GPIO功能時(shí),就要配置GPIO外設(shè)中的各個(gè)寄存器(DR、GDIR、PSR...)。
⑤ 與其它引腳的連接:這里是另一個(gè)引腳PAD2,它與PAD1有一根信號(hào)線連接,表示部分引腳的輸出可以作為另一個(gè)引腳的輸入。
1.2.1 PAD配置
PAD代表示i.MX6ULL 的GPIO引腳。其左側(cè)是一系列信號(hào)通道及控制線:
input_on控制輸入開關(guān)
Dir 控制引腳的輸入輸出方向
Data_out 控制引腳輸出高低電平
Data_in 作為信號(hào)輸入
這些信號(hào)都經(jīng)過一個(gè)IOMUX器件連接到左側(cè)的寄存器。
另外,對(duì)于每個(gè)引腳都有很多關(guān)于屬性的配置:
① PAD引腳
框圖最右側(cè)的PAD同樣是代表一個(gè)i.MX6ULL引腳。
② 輸出緩沖區(qū)(OBE,output buffer enable)
當(dāng)輸出緩沖區(qū)使能時(shí),引腳被配置為輸出模式。該模式又包含了如下的屬性配置:
DSE 驅(qū)動(dòng)能力配置:通過調(diào)整芯片內(nèi)部與引腳串聯(lián)電阻 R0 的大小,從而改變引腳的驅(qū)動(dòng)能力。可以把R0的值配置為原值的1/2、1/3?1/7 等。
SRE 壓擺率配置:指電壓轉(zhuǎn)換速率,即電壓由波谷升到波峰的時(shí)間。增大壓擺率可減少輸出電壓的上升時(shí)間。
SPEED 帶寬配置:帶寬的意思是能通過這個(gè)IO口最高的信號(hào)頻率,可設(shè)置為50MHz、100MHz以及200MHz。
ODE 開漏輸出配置:開漏輸出模式常用在一些通訊總線中,如I2C。
③ 輸入緩沖區(qū)(IBE,input buffer enable)
當(dāng)輸入緩沖區(qū)使能時(shí),引腳被配置為輸入模式。該模式又包含了如下的屬性配置:
HYS 滯后使能:i.MX6ULL的輸入檢測(cè)可以使用普通的 CMOS 檢測(cè)或施密特觸發(fā)器模式(滯后模式)。
④ Pull/Keeper上下拉、保持器
引腳的控制中還包含了上下拉、保持器的功能。
PUS 上下拉配置:可選為100K歐下拉以及22K歐、47K歐及100K歐上拉。
PUE 上下拉、保持器選擇:上下拉功能和保持器功能是二選一的,可以通過PUE來選擇。
PKE 上下拉、保持器配置:上下拉功能和保持器還通過PKE來控制是否使能。
1.2.2 IOMUX復(fù)用選擇器
與STM32的引腳復(fù)用功能類似,i.MX6ULL芯片的每個(gè)GPIO通過IOMUX設(shè)置,可以支持多種功能。
IOMUX由其左側(cè)的IOMUXC提供寄存器給用戶進(jìn)行配置,它又分成MUX_Mode(IO 模式控制)以及Pad Settings(Pad 配置)兩個(gè)部分:
① MUX_Mode配置:用來配置引腳的復(fù)用功能
② Pad Settings 配置:配置引腳的屬性,例如驅(qū)動(dòng)能力,是否使用上下拉電阻,是否使用保持器,是否使用開漏模式以及使用施密特模式還是CMOS模式等
在IOMUXC外設(shè)中關(guān)于MUX_Mode和Pad Settings寄存器命名格式如下:
IOMUXC 控制類型 | 寄存器名稱 |
---|---|
MUX_Mode | IOMUXC_SW_MUX_CTL_PAD_XXXX |
Pad Settings | IOMUXC_SW_PAD_CTL_PAD_XXXX |
1.3 GPIO命名
1.3.1 按照GPIO分組
i.MX6ULL芯片的GPIO被分成 5 組, 并且每組GPIO的數(shù)量不盡相同,例如GPIO1有32個(gè)引腳,GPIO2有22個(gè)引腳等等:
GPIO組 | 引腳數(shù) | 名稱 |
---|---|---|
GPIO1 | 32 | GPIO1_IO0~GPIO1_IO31 |
GPIO2 | 22 | GPIO2_IO0~GPIO2_IO21 |
GPIO3 | 29 | GPIO3_IO0~GPIO3_IO28 |
GPIO4 | 29 | GPIO4_IO0~GPIO4_IO28 |
GPIO5 | 12 | GPIO5_IO0~GPIO5_IO11 |
具體可查閱數(shù)據(jù)手冊(cè):
1.3.2 按照IO分組
此外,還有另一種命名方式,因?yàn)镚PIO是屬于IO的一種,因此按照I.MX6ULL的IO分類,可以分為兩大類:SNVS域的IO和通用的IO,這兩類IO本質(zhì)上是一樣的。
IO類別 | 命名類型 |
---|---|
SNVS域的IO | IOMUXC_SNVS_SW_MUX_CTL_PAD_XX_XX |
通用的IO | IOMUXC_SW_MUX_CTL_PAD_XX_XX |
SNVS域的IO: 命名形式為IOMUXC_SNVS_SW_MUX_CTL_PAD_XX_XX
XX_XX
可以是如: BOOT_MODE0、SNVS_TAMPER0、TEST_MODE等。
通用的IO: 命名形式為IOMUXC_SW_MUX_CTL_PAD_XX_XX
XX_XX
可以是如: GPIO1_IO01、UART1_TX_DATA、JTAG_MOD等。
所以,從IO名稱上,基本就可以看出該管腳的基本用途。
2 板子LED引腳配置
下面以 GPIO5_IO03引腳為例,也就是這次要控制的LED引腳,進(jìn)行配置:
2.1 IO配置
2.1.1 配置MUX寄存器
從下圖可以看出,IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3的MUX寄存器,其地址為0X2290014H。
這個(gè)寄存器是32位的,但只用到了低5位,其中bit0~bit3(MUX_MODE)就是設(shè)置SNVS_TAMPER3的復(fù)用功能的。
SNVS_TAMPER3只能復(fù)用為 種功能 IO,即ALT5作為 GPIO5_IO03。
2.1.2 配置PAD寄存器
PAD 寄存器的配置項(xiàng)相對(duì)于MUX寄存器就更加豐富了。
從下圖可以看出,IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3的PAD寄存器,其地址為0X2290058H。
這也是個(gè)32位寄存器,但是只用到了其中的低17位。
2.2 GPIO配置
上面的MUX和PAD這兩種寄存器都是配置IO的,當(dāng)把IO配置為了GPIO功能后,還有繼續(xù)對(duì)GPIO外設(shè)的各種寄存器進(jìn)行配置:
2.2.1 配置DR寄存器
DR(data register),即數(shù)據(jù)寄存器,它是32位的,一個(gè)GPIO組最大只有32個(gè)IO,因此DR寄存器中的每個(gè)位都對(duì)應(yīng)一個(gè) GPIO。
當(dāng)GPIO被配置為輸出模式后,向指定的位寫入數(shù)據(jù)那么相應(yīng)的IO就會(huì)輸出相應(yīng)的高低電平,例如,要設(shè)置GPIO5_IO03輸出低電平,那么就應(yīng)該設(shè)置 GPIO5.DR=0x08。
當(dāng) GPIO被配置為輸入模式后,此寄存器就保存著對(duì)應(yīng)IO的電平值,每個(gè)位對(duì)對(duì)應(yīng)一個(gè)GPIO,例如,當(dāng)GPIO5_IO03這個(gè)引腳接地的話,那么 GPIO5.DR 的bit3就是0。
2.2.2 配置GDIR寄存器
GDIR(GPIO direction register),即方向寄存器,也是32位的,用來設(shè)置某個(gè)GPIO的工作方向的,即輸入/輸出。
同樣的,每個(gè)IO對(duì)應(yīng)一個(gè)位,如果要設(shè)置GPIO為輸入,就設(shè)置相應(yīng)的位為0,如果要設(shè)置為輸出,就設(shè)置為 1。
比如要設(shè)置 GPIO5_IO03 為輸出,那么 GPIO5.GDIR=0x00;
2.2.3 配置PSR寄存器
PSR(Pad Status Register),即狀態(tài)寄存器,也是32位的。
注意它是一個(gè)只讀寄存器,每個(gè)IO對(duì)應(yīng)一個(gè)位,讀取相應(yīng)的位即可獲取對(duì)應(yīng)的GPIO的狀(高低電平值),功能和輸入狀態(tài)下的DR寄存器一樣。
這個(gè)寄存器使用ipg_clk_s時(shí)鐘,這意味著只有在訪問這個(gè)位時(shí)才對(duì)輸入信號(hào)進(jìn)行采樣。所以,為了同步訪問這個(gè)寄存器都需要兩個(gè)等待狀態(tài)。
2.2.4 配置ICR1寄存器
ICR1(interrupt configuration register1)和ICR2,都是中斷控制寄存器, ICR1用于配置低16個(gè)GPIO,ICR2 用于配置高16 個(gè)GPIO。
ICR1寄存器中一個(gè)GPIO用兩個(gè)位,這兩個(gè)位用來配置中斷的觸發(fā)方式:
位設(shè)置 | 中斷觸發(fā)方式 |
---|---|
00 | 低電平觸發(fā) |
01 | 高電平觸發(fā) |
10 | 上升沿觸發(fā) |
11 | 下降沿觸發(fā) |
以GPIO1_IO15為例, 若要設(shè)置該引腳為上升沿觸發(fā)中斷, 需要配置為:GPIO1.ICR1=2<<30。
2.2.5 配置ICR2寄存器
ICR1和ICR2(interrupt configuration register2),都是中斷控制寄存器, ICR1用于配置低16個(gè)GPIO,ICR2 用于配置高16 個(gè)GPIO。
若要設(shè)置GPIO1的IO16~31的話就需要設(shè)置ICR2寄存器了,設(shè)置方式參考上面的ICR1。下面這個(gè)圖與ICR1類似,只截取部分顯示。
2.2.6 配置IMR寄存器
IMR(interrupt mask register),即中斷屏蔽寄存器,也是32位,每個(gè)IO對(duì)應(yīng)一個(gè)位。
IMR寄存器用來控制GPIO的中斷禁止和使能,如果使能某個(gè)GPIO的中斷,那么設(shè)置相應(yīng)的位為1即可,反之,如果要禁止中斷,那么就設(shè) 置相應(yīng)的位為0即可。
例如,要使能GPIO1_IO00的中斷,需要配置為GPIO1.MIR=1。
2.2.7 配置ISR寄存器
ISR(interrupt status register),即中斷狀態(tài)寄存器,也是32位,每個(gè)IO對(duì)應(yīng)一個(gè)位。
只要某個(gè)GPIO的中斷發(fā)生,則ISR中相應(yīng)的位就會(huì)被置1。所以通過讀取ISR寄存器來判斷是否發(fā)生了中斷,類似于學(xué)習(xí)STM32用到的中斷標(biāo)志位。
當(dāng)中斷處理完以后,必須清除中斷標(biāo)志位,清除方法就是向ISR中相應(yīng)的位寫1,也就是寫1清零。
為了同步,讀訪問需要兩個(gè)等待狀態(tài),復(fù)位需要一個(gè)等待狀態(tài)。
2.2.8 配置EDGE_SEL寄存器
EDGE_SEL(edge select register),即邊沿選擇寄存器,也是32位,每個(gè)IO對(duì)應(yīng)一個(gè)位。
它用來設(shè)置邊沿中斷, 并會(huì)覆蓋ICR1和ICR2的設(shè)置。
如果相應(yīng)的位被置1,則相當(dāng)于設(shè)置了對(duì)應(yīng)的GPIO是雙邊沿(上升沿和下降沿)觸發(fā)。例如,設(shè)置GPIO1.EDGE_SEL=1,則表示 GPIO1_IO01是雙邊沿觸發(fā)中斷,無論 GFPIO1_CR1的設(shè)置為多少。
2.3 GPIO各寄存器地址查詢表
上面介紹的有關(guān)GPIO的7種寄存器,為了方便查詢各個(gè)寄存器的地址,這里列出一張表:
2.4 時(shí)鐘配置
與ST32類似,I.MX6ULL每個(gè)外設(shè)都有一個(gè)外設(shè)時(shí)鐘,使用GPIO時(shí),也必須先使能對(duì)應(yīng)的時(shí)鐘。
2.4.1 配置CCM寄存器
CCM(Clock Controller Module)時(shí)鐘控制模塊寄存器用來使能外設(shè)時(shí)鐘。 CMM一共有CCM_CCGR0~CCM_CCGR6這 7 個(gè)寄存器,控制著I.MX6U的所有外設(shè)時(shí)鐘開關(guān)。
GPIOx | CCGRx(addr) | CGx |
---|---|---|
GPIO1_CLK_ENABLE | CCGR1(0X020C406C) | CG13 |
GPIO2_CLK_ENABLE | CCGR0(0X020C4068) | CG15 |
GPIO3_CLK_ENABLE | CCGR2(0X020C4070) | CG13 |
GPIO4_CLK_ENABLE | CCGR3(0X020C4074) | CG6 |
GPIO5_CLK_ENABLE | CCGR1(0X020C406C) | CG15 |
以CCM_CCGR0為例,它是個(gè)32位寄存器,每2位控制一個(gè)外設(shè)的時(shí)鐘,比如 bit31:30 控制著GPIO2 的外設(shè)時(shí)鐘,兩個(gè)位就有 4 種操作方式:
位設(shè)置 | 時(shí)鐘控制 |
---|---|
00 | 所有模式下都關(guān)閉外設(shè)時(shí)鐘 |
01 | 只有在運(yùn)行模式下打開外設(shè)時(shí)鐘,等待模式和停止模式下均關(guān)閉外設(shè)時(shí)鐘 |
10 | 未使用(保留) |
11 | 除了停止模式以外,其他所有模式下時(shí)鐘都打開 |
若要打開GPIO2的外設(shè)時(shí)鐘,只需要設(shè)置CCM_CCGR0的bit31和bit30為1即可,即 CCM_CCGR0=3 << 30。
2.5 配置總結(jié)
使用i.MX6ULL的GPIO時(shí),需要如下幾步配置:
使能 GPIO 對(duì)應(yīng)的時(shí)鐘
配置MUX寄存器,設(shè)置IO的復(fù)用功能,使其復(fù)用為GPIO功能
配置PAD寄存器,設(shè)置 IO 的上下拉、速度等
配置GPIO的各種寄存器(DR、GDIR、...),設(shè)置輸入/輸出、是否使用中斷、默認(rèn)輸出電平等
通過上面對(duì)各種寄存器的介紹,現(xiàn)在再來看本篇開頭提到的那幾個(gè)寄存器地址,如果理解了本篇的介紹,應(yīng)該就知道這些地址大概的含義了:
/* 寄存器物理地址 */
#define CCM_CCGR1_BASE (0X020C406C)
#define SW_MUX_SNVS_TAMPER3_BASE (0X02290014)
#define SW_PAD_SNVS_TAMPER3_BASE (0X02290058)
#define GPIO5_DR_BASE (0X020AC000)
#define GPIO5_GDIR_BASE (0X020AC004)
3 總結(jié)
本篇主要介紹了i.MX6ULL有關(guān)GPIO的寄存器配置原理,本篇是i.MX6ULL操作硬件電路的基礎(chǔ),了解了這些寄存器的配置原理,后續(xù)的LED輸出控制、按鍵輸入控制、IIC、SPI通信控制才能更加容易理解。
審核編輯:湯梓紅
-
寄存器
+關(guān)注
關(guān)注
31文章
5300瀏覽量
119860 -
Linux
+關(guān)注
關(guān)注
87文章
11213瀏覽量
208736 -
GPIO
+關(guān)注
關(guān)注
16文章
1189瀏覽量
51846
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論