SMDKC110的GPIO引腳相對來說比較多,而且大部分引腳都具有多重複用功能,如何在linux上用最簡單的方式來控制GPIO這需要我們好好研究一下底層的代碼了,其實方法有很多種,鑑於在操作系統端控制GPIO並不像控制傳統的單片機那樣。
這裏我將提及一種方法來講述,這種方法也是我至今看到最簡單的方法
首先我們打開linux-3.0.1\arch\arm\plat-samsung\include\plat下gpio-cfg.h這個頭文件,仔細瀏覽後發現,我們可以使用的函數:
1.設置單一io口
int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
裏面有兩個參數,第一個pin是選擇哪個引腳,第二個參數有三種定義
設置成輸出模式 #define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0))
設置成輸入模式 #define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1))
複用功能選擇 #define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x))
其實根據我使用的情況來說第1,2兩個定義根本就是雞肋,只有第3個S3C_GPIO_SFN(x)纔是最有用的,舉個例子:
Ok6410的開發板的DS18B20的接口,器件被接在GPE0上,而GPE有如下複用功能
其中的參數x就是對應上表的複用功能,當x=0時是輸入功能,x=1時是輸出功能......下面我想不用我說大家也明白了吧。
這個例子s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(1));說明GPE0口配置爲輸出模式。
1.獲取io口的配置
unsigned s3c_gpio_getcfg(unsigned int pin);這個函數跟上面講到的剛好相反,是讀取當前一個io口的配置,pin參數是要獲得的引腳配置,函數會返回一個相應的值
2.設置一組io
int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, unsigned int cfg);
第一個參數start是開始的引腳,第二個nr是從start開始到第一個,注意配置的io必須是同一組的io,第三個cfg是配置狀態
3.設置單一io的上拉電阻
int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
設置單個io爲不同的上拉模式,模式分別爲
S3C_GPIO_PULL_NONE
S3C_GPIO_PULL_DOWN
S3C_GPIO_PULL_UP
5.獲取io口的上拉電阻配置
s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
獲取單個io的上拉配置狀態,會返回一個配置模式
6.設置一組io(包括上拉電阻)
int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, unsigned int cfg, s3c_gpio_pull_t pull);
講了這麼多看到最後一個函數不講也應該能看出到底是如何配置了吧
講了這麼多io口的配置方法,來看看如何來配置輸出的電平狀態。
打開linux-3.0.1\include\linux下的gpio.h的頭文件,發現裏面有好多的引腳函數其中最重要的也就這麼幾句
1.設置一個引腳的電平狀態
static inline void gpio_set_value(unsigned gpio, int value)
第一個參數gpio爲指定的引腳,第二個參數value爲要設置的高低電平
2.獲得一個引腳的電平狀態
static inline int gpio_get_value(unsigned gpio)
第一個參數爲gpio爲指定的引腳,會返回一個電平狀態
講了上面這些我們基本能控制一個io了,現在我在介紹一種方法,這種方法只能進行輸入和輸出不能進行io的複用配置
1.io輸出
static inline int gpio_direction_output(unsigned gpio, int value)
第一個參數gpio爲指定的引腳,第二個參數爲電平狀態
2.io輸入
static inline int gpio_direction_input(unsigned gpio)
第一個參數gpio爲指定的引腳,會返回一個電平狀態
出了上面方法外我們還可以直接對gpio的地址訪問,linux已經爲我們準備了這樣的接口函數
#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
其中的a值爲
S3C64XX_GPMCON
S3C64XX_GPMPUD
S3C64XX_GPMDAT
在reg-gpio.h中已經有了以上的定義
V爲具體的數值。