轉發自個人博客:http://blog.sina.com.cn/s/blog_b5020b670101ft49.html
uboot的GPIO至關簡單,其就是三層結構。分別爲: 一、頂層接口層,其只定義了通用的接口,並不負責實現,實現是咱們具體根據具體的芯片來實現的。
二、中間接口實現層,用具體的板子的GPIO來實現頂層的接口
三、 底層具體芯片GPIO的實現層 。
如今具體分析:
頂層接口層
int gpio_request(unsigned gpio, const char *label); //申請GPIO資源
int gpio_free(unsigned gpio); //釋放申請的GPIO資源
int gpio_direction_input(unsigned gpio); //設置GPIO爲輸入模式
int gpio_direction_output(unsigned gpio, int value); //設置GPIO爲輸出模式
int gpio_get_value(unsigned gpio); //獲得GPIO的值
int gpio_set_value(unsigned gpio, int value);//設置GPIO的值
說明:unsigned gpio爲邏輯號,雖然和實際的物理GPIO地址有必定的關係,但並非實際的物理GPIO地址。
中間接口實現層:
用具體的芯片的GPIO來實現其頂層接口
int gpio_request(unsigned gpio, const char *label)
{
return 0;
}
int gpio_free(unsigned gpio)
{
return 0;
}
int gpio_direction_input(unsigned gpio)
{
sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
return sunxi_gpio_input(gpio);
}
int gpio_direction_output(unsigned gpio, int value)
{
sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
return sunxi_gpio_output(gpio, value);
}
int gpio_get_value(unsigned gpio)
{
return sunxi_gpio_input(gpio);
}
int gpio_set_value(unsigned gpio, int value)
{
return sunxi_gpio_output(gpio, value);
}
底層具體芯片GPIO的實現層:
在實現的時候,其用了一個小技巧,其目的是把GPIO的物理寄存器放到結構體裏面來,從而把物理的地址操做轉換爲數據結構的操做。
其實現以下:
把SUNXI_PIO_BASE 強制轉換爲sunxi_gpio_reg *指針來實現。
#define SUNXI_PIO_BASE 0x01c20800
struct sunxi_gpio {
u32 cfg[4];
u32 dat;
u32 drv[2];
u32 pull[2];
};
struct sunxi_gpio_int {
u32 cfg[3];
u32 ctl;
u32 sta;
u32 deb;
};
struct sunxi_gpio_reg {
struct sunxi_gpio gpio_bank[9];
u8 res[0xbc];
struct sunxi_gpio_int gpio_int;
};
咱們實現具體的芯片的GPIO的操做的思想是:
使用邏輯符號unsigned gpio,經過SUNXI_PIO_BASE 強制轉換爲sunxi_gpio_reg *指針的指針來操做相關寄存器。
可是邏輯符號unsigned gpio要經過SUNXI_PIO_BASE 強制轉換爲sunxi_gpio_reg *指針的指針來操做相關寄存器,必需要解決一個問題,即如何在衆多的寄存器的中,找到指定的那個寄存器,而且在該寄存器上找到指定的那些相關位。
即gpio---->bank------>bank中的offset
這個映射關係和具體的芯片有關。
這裏只討論全志的a10芯片。
後面的寫不了了,想看完整版的請看個人博客:http://blog.sina.com.cn/s/blog_b5020b670101ft49.html
php
原文做者:毅哥html
原文連接:http://forum.cubietech.com/forum.php?mod=viewthread&tid=1791&extra=page%3D1數據結構