[英]How to use I2C GPIO expander's pin instead of RTS to control the RS485 direction, in Linux AUART kernel driver?
我正在基於NXP(Freescale)的i.MX287處理器創建一個嵌入式系統。 我正在使用一個通過迷你PCIe連接器連接到我的評估板上的核心處理板。
UART 0、3、4用作RS232,而UART 1,2用作RS485。 核心板不在其引腳上提供RTS信號,因此我必須使用I2C GPIO擴展器中的引腳來控制RS485方向。 GPIO擴展器模塊還用於控制板上的其他一些設備。
在用戶空間中,我可以使用libi2c控制方向針,但是我的客戶要求我將方向針控制放在UART驅動程序中。
問題:
1-如何與auart驅動程序中的i2c設備進行交互? (可能嗎)
2-如果可能,那么如何防止i2c-0總線被內核阻塞? (我還需要對libi2c的userspace調用才能正常工作)
我在Google上搜索了很多,但是大多數情況是關於如何使用I2C驅動程序或如何在sysfs中激活GPIO引腳的,我能夠做到所有這些。
libi2c用於用戶空間,所以我不能在這里調用它。 我也知道在內核中打開文件(/ dev / i2c-0)並對其進行讀寫不是一個好主意。 我試圖了解什么是處理此問題的最佳方法,而又不會引起任何並發訪問問題。
我將不勝感激
PS-
編輯1:根據@ 0andriy的建議,我編輯了DTS文件,並將以下內容添加到/arch/arm/boot/dts/my_dts_file.dts
:
/dts-v1/;
#include "imx28.dtsi"
/ {
// some definitions
apbx@80040000 {
i2c0: i2c@80058000 {
pca8575: gpio@20 {
compatible = "nxp,pca8575";
reg = <0x20>; // PCA8575PW Address -0-0-0
gpio-controller;
#gpio-cells = <2>;
};
};
auart1: serial@8006c000 {
pinctrl-names = "default";
pinctrl-0 = <&auart1_2pins_a>;
linux,rs485-enabled-at-boot-time;
rs485-rts-delay = <0 0>; // in milliseconds
rts-gpios = <&pca8575 4 GPIO_ACTIVE_LOW>;
rs485-rts-active-low;
status = "okay";
};
auart2: serial@8006e000 {
pinctrl-names = "default";
pinctrl-0 = <&auart2_2pins_b>;
linux,rs485-enabled-at-boot-time;
rs485-rts-delay = <0 0>; // in milliseconds
rts-gpios = <&pca8575 5 GPIO_ACTIVE_LOW>;
rs485-rts-active-low;
status = "okay";
};
};
// some definitions
};
然后重建內核。 我還編輯了mxs_auart_init_gpios
-auart.c驅動程序中的mxs_auart_init_gpios
函數,以在啟動時打印所有auart GPIO的引腳說明。 但是gpiod = mctrl_gpio_to_gpiod(s->gpios, i)
始終為NULL。 未在/sys/class/gpio/
下添加pca8575 GPIO控制器
root# ls /sys/class/gpio
export gpiochip128 gpiochip64 unexport
gpiochip0 gpiochip32 gpiochip96
編輯2:
來自imx28.dtsi
文件的auart1_2pins_a
和auart2_2pins_b
:
auart2_2pins_b: auart2-2pins@1 {
reg = <1>;
fsl,pinmux-ids = <
MX28_PAD_AUART2_RX__AUART2_RX
MX28_PAD_AUART2_TX__AUART2_TX
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
fsl,pull-up = <MXS_PULL_DISABLE>;
};
auart1_2pins_a: auart1-2pins@0 {
reg = <0>;
fsl,pinmux-ids = <
MX28_PAD_AUART1_RX__AUART1_RX
MX28_PAD_AUART1_TX__AUART1_TX
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
fsl,pull-up = <MXS_PULL_DISABLE>;
};
我正在使用內核4.14.13
我對您的董事會完全不熟悉,因此請稍作調整,但我注意到您的文件中有一些有趣的事情。
首先,您需要定義要用於在UART pinmux內部切換方向的I2C引腳:
auart2_2pins_b: auart2-2pins@1 {
reg = <1>;
fsl,pinmux-ids = <
MX28_PAD_AUART2_RX__AUART2_RX
MX28_PAD_AUART2_TX__AUART2_TX
MX28_PAD_I2C0_SCL__I2C0_SCL
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
fsl,pull-up = <MXS_PULL_DISABLE>;
};
確保您仔細檢查要使用的引腳名稱,但我不確定這是正確的名稱。
然后,您似乎缺少了I2C控制器的pinctrl
:
i2c0: i2c@80058000 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_a>;
status = "okay";
pca8575: gpio@20 {
compatible = "nxp,pca8575";
reg = <0x20>; // PCA8575PW Address -0-0-0
gpio-controller;
#gpio-cells = <2>;
};
};
我無法確認您的reg
和您的密碼,但我假設您是從董事會文檔中獲取的。 如果沒有,請確保找到硬件的可靠來源。
最后,我不確定為什么要使RTS線路為低電平有效,大多數收發器都有DE /〜RE輸入,這意味着您需要使線路為高電平來驅動總線。 也許你的司機不一樣...
您正在嘗試做的事情被證明可以在其他主板上使用,所以我想除非有錯誤,您應該能夠使它工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.