在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Firefly-RK3288--GPIO主板介紹

firefly ? 來源:firefly ? 作者:firefly ? 2019-11-26 17:16 ? 次閱讀
GPIO 使用
簡介

GPIO, 全稱 General-Purpose Input/Output(通用輸入輸出),是一種軟件運行期間能夠動態配置和控制的通用引腳。 RK3288 有 9 組 GPIO bank: GPIO0,GPIO1, …, GPIO8。每組又以 A0~A7, B0~B7, C0~C7, D0~D7 作為編號區分(不是所有 bank 都有全部編號,例如 GPIO5 就只有 B0~B7, C0~C3)。

每個 GPIO 口除了通用輸入輸出功能外,還可能有其它復用功能,例如 GPIO5_B4,可以復用成以下功能之一:

  • spi0_clk
  • ts0_data4
  • uart4exp_ctsn

每個 GPIO 口的驅動電流、上下拉和重置后的初始狀態都不盡相同,詳細情況請參考《RK3288 規格書》中的 “RK3288 function IO description” 一章。

RK3288 的 GPIO 驅動是在以下 pinctrl 文件中實現的:

kernel/drivers/pinctrl/pinctrl-rockchip.c

其核心是填充 GPIO bank 的方法和參數,并調用 gpiochip_add 注冊到內核中。

使用

開發板有兩個電源 LED 燈是 GPIO 口控制的,分別是:

從電路圖上看,GPIO 口輸出低電平時燈亮,高電平時燈滅。 另外,擴展槽上引出了幾個空閑的 GPIO 口,分別是:

這幾個 GPIO 口可以自定義作輸入、輸出使用。

輸入輸出

下面以電源 LED 燈的驅動為例,講述如何在內核編寫代碼控制 GPIO 口的輸出。 首先需要在 dts (Device Tree) 文件 firefly-rk3288.dts 中增加驅動的資源描述:

firefly-led{ compatible = "firefly,led"; led-work = <&gpio8 GPIO_A2 GPIO_ACTIVE_LOW>; led-power = <&gpio8 GPIO_A1 GPIO_ACTIVE_LOW>; status = "okay"; };

這里定義了兩顆 LED 燈的 GPIO 設置:

led-work GPIO8_A2 GPIO_ACTIVE_LOW led-power GPIO8_A1 GPIO_ACTIVE_LOW

GPIO_ACTIVE_LOW 表示低電平有效(燈亮),如果是高電平有效,需要替換為 GPIO_ACTIVE_HIGH 。 之后在驅動程序中加入對 GPIO 口的申請和控制則可:

#ifdef CONFIG_OF #include #include #endif static int firefly_led_probe(struct platform_device *pdev){ int ret = -1;int gpio, flag; struct device_node *led_node = pdev->dev.of_node; gpio = of_get_named_gpio_flags(led_node, "led-power", 0, &flag); if (!gpio_is_valid(gpio)){ printk("invalid led-power: %d\n",gpio); return -1; } if (gpio_request(gpio, "led_power")) { printk("gpio %d request failed!\n",gpio); return ret; } led_info.power_gpio = gpio; led_info.power_enable_value = (flag == OF_GPIO_ACTIVE_LOW) ? 0 : 1; gpio_direction_output(led_info.power_gpio, !(led_info.power_enable_value)); ... on_error:gpio_free(gpio); }

of_get_named_gpio_flags 從設備樹中讀取 led-power 的 GPIO 配置編號和標志,gpio_is_valid 判斷該 GPIO 編號是否有效,gpio_request 則申請占用該 GPIO。如果初始化過程出錯,需要調用 gpio_free 來釋放之前申請過且成功的 GPIO 。 調用 gpio_direction_output 就可以設置輸出高還是低電平,因為是 GPIO_ACTIVE_LOW ,如果要燈亮,需要寫入 0 。 實際中如果要讀出 GPIO,需要先設置成輸入模式,然后再讀取值:

int val; gpio_direction_input(your_gpio); val = gpio_get_value(your_gpio);

下面是常用的 GPIO API 定義:

#include #include enum of_gpio_flags {OF_GPIO_ACTIVE_LOW = 0x1,}; int of_get_named_gpio_flags(struct device_node *np, const char *propname,int index, enum of_gpio_flags *flags); int gpio_is_valid(int gpio); int gpio_request(unsigned gpio, const char *label); void gpio_free(unsigned gpio); int gpio_direction_input(int gpio); int gpio_direction_output(int gpio, int v)
復用

如何定義 GPIO 有哪些功能可以復用,在運行時又如何切換功能呢?以 I2C4 為例作簡單的介紹。 查規格表可知,I2C4_SDA 與 I2C4_SCL 的功能定義如下:

在 /kernel/arch/arm/boot/dts/rk3288.dtsi 里有:

i2c4: i2c@ff160000 { compatible = "rockchip,rk30-i2c"; reg = <0xff160000 0x1000>; interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default", "gpio"; pinctrl-0 = <&i2c4_sda &i2c4_scl>; pinctrl-1 = <&i2c4_gpio>; gpios = <&gpio7 GPIO_C1 GPIO_ACTIVE_LOW>, <&gpio7 GPIO_C2 GPIO_ACTIVE_LOW>; clocks = <&clk_gates6 15>; rockchip,check-idle = <1>; status = "disabled"; };
  • 此處,跟復用控制相關的是 pinctrl- 開頭的屬性:
    • pinctrl-names 定義了狀態名稱列表: default (i2c 功能) 和 gpio 兩種狀態。
    • pinctrl-0 定義了狀態 0 (即 default)時需要設置的 pinctrl: i2c4_sda 和 i2c4_scl
    • pinctrl-1 定義了狀態 1 (即 gpio)時需要設置的 pinctrl: i2c4_gpio

這些 pinctrl 在 /kernel/arch/arm/boot/dts/rk3288-pinctrl.dtsi 中定義:

/ { pinctrl: pinctrl@ff770000 { compatible = "rockchip,rk3288-pinctrl"; ... gpio7_i2c4 { i2c4_sda:i2c4-sda { rockchip,pins = <I2C4TP_SDA>; rockchip,pull = <VALUE_PULL_DISABLE>; rockchip,drive = <VALUE_DRV_DEFAULT>; //rockchip,tristate = <VALUE_TRI_DEFAULT>; }; i2c4_scl:i2c4-scl { rockchip,pins = <I2C4TP_SCL>; rockchip,pull = <VALUE_PULL_DISABLE>; rockchip,drive = <VALUE_DRV_DEFAULT>; //rockchip,tristate = <VALUE_TRI_DEFAULT>; }; i2c4_gpio: i2c4-gpio { rockchip,pins = <FUNC_TO_GPIO(I2C4TP_SDA)>, <FUNC_TO_GPIO(I2C4TP_SCL)>; rockchip,drive = <VALUE_DRV_DEFAULT>; }; }; ... } }

I2C4TP_SDA, I2C4TP_SCL 的定義在 /kernel/arch/arm/boot/dts/include/dt-bindings/pinctrl/rockchip-rk3288.h 中:

#define GPIO7_C1 0x7c10 #define I2C4TP_SDA 0x7c11 #define GPIO7_C2 0x7c20 #define I2C4TP_SCL 0x7c21

FUN_TO_GPIO 的定義在 /kernel/arch/arm/boot/dts/include/dt-bindings/pinctrl/rockchip.h 中:

#define FUNC_TO_GPIO(m) ((m) & 0xfff0)

也就是說 FUNC_TO_GPIO(I2C4TP_SDA) == GPIO7_C1, FUNC_TO_GPIO(I2C4TP_SCL) == GPIO7_C2 。 像 0x7c11 這樣的值是有編碼規則的:

7 c1 1 | | `- func | `---- offset `------ bank 0x7c11 就表示 GPIO7_C1 func1, 即 i2c4tp_sda 。

在復用時,如果選擇了 “default” (即 i2c 功能),系統會應用 i2c4_sda 和 i2c4_scl 這兩個 pinctrl,最終得將 GPIO7_C1 和 GPIO7_C2 兩個針腳切換成對應的 i2c 功能;而如果選擇了 “gpio” ,系統會應用 i2c4_gpio 這個 pinctrl,將 GPIO7_C1 和 GPIO7_C2 兩個針腳還原為 GPIO 功能。

我們看看 i2c 的驅動程序 /kernel/drivers/i2c/busses/i2c-rockchip.c 是如何切換復用功能的:

static int rockchip_i2c_probe(struct platform_device *pdev){ struct rockchip_i2c *i2c = NULL; struct resource *res; struct device_node *np = pdev->dev.of_node; int ret; // ... i2c->sda_gpio = of_get_gpio(np, 0); if (!gpio_is_valid(i2c->sda_gpio)) { dev_err(&pdev->dev, "sda gpio is invalid\n"); return -EINVAL; } ret = devm_gpio_request(&pdev->dev, i2c->sda_gpio, dev_name(&i2c->adap.dev)); if (ret) { dev_err(&pdev->dev, "failed to request sda gpio\n"); return ret; } i2c->scl_gpio = of_get_gpio(np, 1); if (!gpio_is_valid(i2c->scl_gpio)) { dev_err(&pdev->dev, "scl gpio is invalid\n"); return -EINVAL; } ret = devm_gpio_request(&pdev->dev, i2c->scl_gpio, dev_name(&i2c->adap.dev)); if (ret) { dev_err(&pdev->dev, "failed to request scl gpio\n"); return ret; } i2c->gpio_state = pinctrl_lookup_state(i2c->dev->pins->p, "gpio"); if (IS_ERR(i2c->gpio_state)) { dev_err(&pdev->dev, "no gpio pinctrl state\n"); return PTR_ERR(i2c->gpio_state); } pinctrl_select_state(i2c->dev->pins->p, i2c->gpio_state); gpio_direction_input(i2c->sda_gpio); gpio_direction_input(i2c->scl_gpio); pinctrl_select_state(i2c->dev->pins->p, i2c->dev->pins->default_state); // ... }

首先是調用 of_get_gpio 取出設備樹中 i2c4 結點的 gpios 屬于所定義的兩個 gpio:

gpios = <&gpio7 GPIO_C1 GPIO_ACTIVE_LOW>, <&gpio7 GPIO_C2 GPIO_ACTIVE_LOW>;

然后是調用 devm_gpio_request 來申請 gpio,接著是調用 pinctrl_lookup_state 來查找 “gpio” 狀態,而默認狀態 “default” 已經由框架保存到 i2c->dev-pins->default_state 中了。最后調用 pinctrl_select_state 來選擇是 “default” 還是 “gpio” 功能。 下面是常用的復用 API 定義:

#include struct device { //... #ifdef CONFIG_PINCTRLstruct dev_pin_info *pins; #endif //... }; struct dev_pin_info { struct pinctrl *p; struct pinctrl_state *default_state; #ifdef CONFIG_PMstruct pinctrl_state *sleep_state; struct pinctrl_state *idle_state; #endif }; struct pinctrl_state * pinctrl_lookup_state(struct pinctrl *p, const char *name); int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11432

    瀏覽量

    212479
  • 嵌入式主板
    +關注

    關注

    7

    文章

    6095

    瀏覽量

    36107
  • 可制造性設計

    關注

    10

    文章

    2065

    瀏覽量

    15956
  • Firefly
    +關注

    關注

    2

    文章

    541

    瀏覽量

    7353
  • 華秋DFM
    +關注

    關注

    20

    文章

    3498

    瀏覽量

    5179
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    請問Firefly-RK3288 reload板子如何從dtsi操作led gpio

    Firefly-RK3288請重新加載板子如何從dtsiled gpio操作?
    發表于 03-03 06:44

    為什么Firefly-RK3288主板燒寫Android固件會失敗呢

    為什么Firefly-RK3288主板燒寫Android固件會失敗呢?怎樣去解決這個問題呢?
    發表于 03-04 07:53

    Firefly-RK3288用戶指南

    Firefly-RK3288 是一個高性能平臺,它擁有強大的多線程運算能力、圖形處理能力以及硬件解碼能力,支持 Android 4.4 和 Ubuntu 雙系統,也是一臺強大的微型
    發表于 10-10 07:35

    Firefly-RK3288--教程

    Firefly-RK3288 的標準套裝包含以下配件:   Firefly-RK3288 主板一塊   WiFi 天線   亞克力
    的頭像 發表于 11-11 16:04 ?4809次閱讀
    <b class='flag-5'>Firefly-RK3288</b>--教程

    Firefly-RK3288--外殼

    外殼 Firefly-RK3288 CAD圖
    的頭像 發表于 11-25 10:14 ?1352次閱讀
    <b class='flag-5'>Firefly-RK3288</b>--外殼

    Firefly-RK3288開發板介紹

    Firefly-RK3288 開發板內置 5 路 UART,分別為 uart0,uart1,uart2,uart3,uart4。 uart0 為 uart_bt,用于藍牙傳輸。
    的頭像 發表于 11-25 10:27 ?3228次閱讀
    <b class='flag-5'>Firefly-RK3288</b>開發板<b class='flag-5'>介紹</b>

    Firefly-RK3288PWM輸出介紹

    Firefly-RK3288 開發板上有 4 路 PWM 輸出,分別為 PWM0 ~ PWM3, 本章主要描述如何配置 PWM。
    的頭像 發表于 11-25 10:31 ?2463次閱讀

    Firefly-RK3288MIPI CSI接口介紹

    Firefly-RK3288 開發板帶有一個 MIPI 攝像頭接口,圖像處理能力達到 4416x3312 像素,支持 4K 視頻錄制。此外,開發板還支持 USB 攝像頭。 本文以 OV13850 攝像頭為例,講解在該開發板上的配置過程。 相關代碼目錄
    的頭像 發表于 11-25 10:38 ?1.1w次閱讀
    <b class='flag-5'>Firefly-RK3288</b>MIPI CSI接口<b class='flag-5'>介紹</b>

    Firefly-RK3288 LED介紹

    Firefly-RK3288 開發板上有 2 個 LED 燈
    的頭像 發表于 11-25 10:39 ?2725次閱讀
    <b class='flag-5'>Firefly-RK3288</b> LED<b class='flag-5'>介紹</b>

    Firefly-RK3288--IR主板介紹

    Firefly-RK3288/Firefly-RK3288-Reload開發板上使用紅外收發傳感器 IR (在 USB OTG 接口和音頻接口之間)實現遙控功能。
    的頭像 發表于 11-26 17:10 ?3097次閱讀
    <b class='flag-5'>Firefly-RK3288</b>--IR<b class='flag-5'>主板</b><b class='flag-5'>介紹</b>

    Firefly-RK3288--I2C主板的使用介紹

    Firefly-RK3288 開發板上有 6 個片上 I2C 控制器。本文主要描述如何在該開發板上配置 I2C。
    的頭像 發表于 11-26 17:00 ?2913次閱讀
    <b class='flag-5'>Firefly-RK3288</b>--I2C<b class='flag-5'>主板</b>的使用<b class='flag-5'>介紹</b>

    Firefly-RK3288--DVP開發板介紹

    Firefly-RK3288-Reload 開發板帶有一個 DVP 攝像頭接口。 本文以 OV5640 攝像頭為例,講解在該開發板上的配置過程。
    的頭像 發表于 11-26 17:19 ?5439次閱讀
    <b class='flag-5'>Firefly-RK3288</b>--DVP開發板<b class='flag-5'>介紹</b>

    Firefly-RK3288ADB主板介紹

    Firefly-RK3288/Firefly-RK3288-Reload 默認是打開USB調試選項。如果需要在關閉或打開USB調試選項,可以 在設置-關于設備-版本號(點擊7次后),然后返回到上一層,可以看到
    的頭像 發表于 10-28 19:22 ?2581次閱讀
    <b class='flag-5'>Firefly-RK3288</b>ADB<b class='flag-5'>主板</b><b class='flag-5'>介紹</b>

    Firefly-RK3288主板啟動教程

    RK3288 有靈活的啟動方式。一般情況下,除非硬件損壞,Firefly-RK3288 開發板是不會變磚的。
    的頭像 發表于 11-27 09:14 ?7163次閱讀
    <b class='flag-5'>Firefly-RK3288</b><b class='flag-5'>主板</b>啟動教程

    Firefly-RK3288產品規格書

    電子發燒友網站提供《Firefly-RK3288產品規格書.pdf》資料免費下載
    發表于 09-15 16:12 ?3次下載
    <b class='flag-5'>Firefly-RK3288</b>產品規格書
    主站蜘蛛池模板: 国产黄色网页 | 婷婷色九月综合激情丁香 | 黄网站视频观看免费 | 真实一级一级一片免费视频 | 人人玩人人弄人人曰 | 国产gaysexchina男同men1068 | 在线播放视频网站 | 视频免费观看视频 | 欧美八区| 欧美伊人久久综合网 | 伊人久久综合网亚洲 | 五月婷婷影院 | 午夜影院在线观看免费 | 欧美色图在线视频 | 色多多成视频人在线观看 | 美女免费观看一区二区三区 | 自偷自拍亚洲欧美清纯唯美 | 日韩一级片免费看 | 国产午夜精品理论片久久影视 | 中韩日欧美电影免费看 | 777丰满影院 | 美女被草视频在线观看 | wwwxx免费| 中文字幕亚洲一区二区v@在线 | 国产精品久久久久免费 | 99热色| 日本不卡高清免费v日本 | 欧美高清激情毛片 | 亚洲一区小说区中文字幕 | 又粗又大又猛又爽免费视频 | a色在线| 亚洲一区免费视频 | 天天干夜夜夜 | 资源新版在线天堂 | jiuse在线 | 国产99在线播放 | 黄色毛片儿 | 国产caoni111在线观看视频 | 中文字幕第十页 | 97se狠狠狠狠狼亚洲综合网 | 六月婷婷在线观看 |