1. 概述
i.MX8QXP Android Automotive12 BSP 默認 I2C1 由 M4 控制,A 核通過 RPMSG 框架操控此 I2C。本篇文章介紹如何把原 BSP 的 RPMSG I2C1 改為 LPI2C。
2. 代碼修改
i.MX8QXP Android Automotive12 BSP 默認 I2C1 由 M4 控制,A 核通過 RPMSG 框架操控此 I2C。本篇文章介紹如何把原 BSP 的 RPMSG I2C1 改為 LPI2C。
2. 代碼修改
2.1 修改 SCFW 資源分配
--- a/platform/board/mx8qx_mek/board.c
+++ b/platform/board/mx8qx_mek/board.c
@@ -778,6 +778,8 @@ sc_err_t mark_shared_resources(sc_rm_pt_t
/* Move some pads not in the M4_0 subsystem */
BRD_ERR(rm_set_pad_movable(pt_src, SC_P_MIPI_CSI0_GPIO0_00,
+ // SC_R_I2C_1,
SC_R_FSPI_0,
SC_R_SECO_MU_4,
SC_R_MU_12B,
@@ -912,8 +916,8 @@ void board_system_config(sc_bool_t early, sc_rm_pt_t pt_boot)
{
RM_RANGE(SC_P_ADC_IN1, SC_P_ADC_IN2),
RM_RANGE(SC_P_FLEXCAN1_RX, SC_P_FLEXCAN1_TX),
- SC_P_USB_SS3_TC1,
- SC_P_USB_SS3_TC3,
+ // SC_P_USB_SS3_TC1,
+ // SC_P_USB_SS3_TC3,
RM_RANGE(SC_P_QSPI0A_DATA0, SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0B)
};
2.2 修改 M4 代碼,去掉 I2C1 控制代碼
① --- a/boards/mekmimx8qx/demo_apps/rear_view_camera/pin_mux.c
+++ b/boards/mekmimx8qx/demo_apps/rear_view_camera/pin_mux.c
@@ -221,12 +221,18 @@ void BOARD_InitPins(sc_ipc_t ipc) /*!< Function assigne
assert(false);
}
#endif
- err = sc_pad_set_all(ipc, BOARD_INITPINS_I2C1_SCL_PIN_FUNCTION_ID, 0U, SC_PAD_CONFIG_OD_IN, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_USB_SS3_TC1 register modification value */
- if (SC_ERR_NONE != err)
- {
- assert(false);
- }
- err = sc_pad_set_all(ipc, BOARD_INITPINS_I2C1_SDA_PIN_FUNCTION_ID, 0U, SC_PAD_CONFIG_OD_IN, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_USB_SS3_TC3 register modificatio
n value */
+// err = sc_pad_set_all(ipc, BOARD_INITPINS_I2C1_SCL_PIN_FUNCTION_ID, 0U, SC_PAD_CONFIG_OD_IN, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_USB_SS3_TC1 register modifica
tion value */
+// if (SC_ERR_NONE != err)
+// {
+// assert(false);
+// }
+// err = sc_pad_set_all(ipc, BOARD_INITPINS_I2C1_SDA_PIN_FUNCTION_ID, 0U, SC_PAD_CONFIG_OD_IN, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_USB_SS3_TC3 register modifica
tion value */
+// if (SC_ERR_NONE != err)
+// {
+// assert(false);
+// }
+
② --- a/boards/mekmimx8qx/demo_apps/rear_view_camera/isi_board.c
+++ b/boards/mekmimx8qx/demo_apps/rear_view_camera/isi_board.c
@@ -143,8 +145,8 @@
#if (!APP_DISPLAY_EXTERNAL_CONVERTOR) || (DPU_EXAMPLE_DI == DPU_DI_LVDS)
-#define IOEXP_I2C ADMA__LPI2C1
-#define IOEXP_I2C_RSRC SC_R_I2C_1
+// #define IOEXP_I2C ADMA__LPI2C1
+// #define IOEXP_I2C_RSRC SC_R_I2C_1
@@ -405,34 +418,35 @@ static status_t BOARD_InitExpansionIO(void)
* Initialize the I2C.
*/
/* open the lpi2c power and clock */
- err = sc_pm_set_resource_power_mode(ipc, IOEXP_I2C_RSRC, SC_PM_PW_MODE_ON);
- if (err != SC_ERR_NONE)
- return kStatus_Fail;
+ // err = sc_pm_set_resource_power_mode(ipc, IOEXP_I2C_RSRC, SC_PM_PW_MODE_ON);
+ // if (err != SC_ERR_NONE)
+ // return kStatus_Fail;
- err = sc_pm_clock_enable(ipc, IOEXP_I2C_RSRC, SC_PM_CLK_PER, true, false);
- if (err != SC_ERR_NONE)
- return kStatus_Fail;
+ // err = sc_pm_clock_enable(ipc, IOEXP_I2C_RSRC, SC_PM_CLK_PER, true, false);
+ // if (err != SC_ERR_NONE)
+ // return kStatus_Fail;
- err = sc_pm_set_clock_rate(ipc, IOEXP_I2C_RSRC, SC_PM_CLK_PER, &i2cClkFreq);
- if (err != SC_ERR_NONE)
- return kStatus_Fail;
+ // err = sc_pm_set_clock_rate(ipc, IOEXP_I2C_RSRC, SC_PM_CLK_PER, &i2cClkFreq);
+ // if (err != SC_ERR_NONE)
+ // return kStatus_Fail;
/* lpi2c init */
- LPI2C_MasterGetDefaultConfig(&masterConfig);
- masterConfig.baudRate_Hz = 100000; //reduce I2C speed for stability
+ // LPI2C_MasterGetDefaultConfig(&masterConfig);
+ // masterConfig.baudRate_Hz = 100000; //reduce I2C speed for stability
- LPI2C_MasterInit(IOEXP_I2C, &masterConfig, i2cClkFreq);
+ // LPI2C_MasterInit(IOEXP_I2C, &masterConfig, i2cClkFreq);
- /*Configure Expansion Pin*/
- /* PCA9646 channel 3 is output to PCA9557. */
- PCA9646_Write(IOEXP_I2C, SWITCH_I2C_ADDR, (1 << 3));
+ // /*Configure Expansion Pin*/
+ // /* PCA9646 channel 3 is output to PCA9557. */
+ // PCA9646_Write(IOEXP_I2C, SWITCH_I2C_ADDR, (1 << 3));
- status = PCA9557_ModifyReg(IOEXP_I2C, CLUSTER_DISPLAY_IOEXP_I2C_ADDR, PCA9557_REG_CONFIGURATION, (1 << CLUSTER_DISPLAY_IOEXP_MIPI_DSI_PIN), 0);
- if (kStatus_Success != status)
- return status;
+ // status = PCA9557_ModifyReg(IOEXP_I2C, CLUSTER_DISPLAY_IOEXP_I2C_ADDR, PCA9557_REG_CONFIGURATION, (1 << CLUSTER_DISPLAY_IOEXP_MIPI_DSI_PIN), 0);
+ // if (kStatus_Success != status)
+ // return status;
- /* Set DSI pin enable and standby pin as output */
- return PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_CONFIGURATION, (1 << IOEXP_MIPI_DSI_PIN), 0);
+ // /* Set DSI pin enable and standby pin as output */
+ // return PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_CONFIGURATION, (1 << IOEXP_MIPI_DSI_PIN), 0);
+ return 0;
}
#if (DPU_EXAMPLE_DI == DPU_DI_MIPI)
@@ -440,11 +454,11 @@ static void RM67191_PullResetPin(bool pullUp)
{
if (pullUp)
{
- PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0xFF);
+ // PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0xFF);
}
else
{
- PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0x00);
+ // PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0x00);
}
}
@@ -458,13 +472,13 @@ static void IT6263_PullResetPin(bool pullUp)
{
if (pullUp)
{
- PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0xFF);
- PCA9557_ModifyReg(IOEXP_I2C, CLUSTER_DISPLAY_IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << CLUSTER_DISPLAY_IOEXP_MIPI_DSI_PIN), 0xFF);
+ // PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0xFF);
+ // PCA9557_ModifyReg(IOEXP_I2C, CLUSTER_DISPLAY_IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << CLUSTER_DISPLAY_IOEXP_MIPI_DSI_PIN), 0xFF);
}
else
{
- PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0x00);
- PCA9557_ModifyReg(IOEXP_I2C, CLUSTER_DISPLAY_IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << CLUSTER_DISPLAY_IOEXP_MIPI_DSI_PIN), 0x00);
+ // PCA9557_ModifyReg(IOEXP_I2C, IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << IOEXP_MIPI_DSI_PIN), 0x00);
+ // PCA9557_ModifyReg(IOEXP_I2C, CLUSTER_DISPLAY_IOEXP_I2C_ADDR, PCA9557_REG_OUTPUT_PORT, (1 << CLUSTER_DISPLAY_IOEXP_MIPI_DSI_PIN), 0x00);
}
}
③ --- a/boards/mekmimx8qx/demo_apps/rear_view_camera/rear_view_camera.c
+++ b/boards/mekmimx8qx/demo_apps/rear_view_camera/rear_view_camera.c
@@ -153,24 +169,33 @@ void BOARD_InitHardware(void)
+
/*
* * LPI2C1
* */
- if (sc_pm_set_resource_power_mode(ipc, SC_R_I2C_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
- {
- PRINTF("Error: Failed to power on LPI2C\r\n");
- }
- if (sc_pm_clock_enable(ipc, SC_R_I2C_1, SC_PM_CLK_PER, true, false) != SC_ERR_NONE)
- {
- PRINTF("Error: Failed to enable SC_R_I2C_1 clock \r\n");
- }
+ // if (sc_pm_set_resource_power_mode(ipc, SC_R_I2C_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+ // {
+ // PRINTF("Error: Failed to power on LPI2C\r\n");
+ // }
+ // if (sc_pm_clock_enable(ipc, SC_R_I2C_1, SC_PM_CLK_PER, true, false) != SC_ERR_NONE)
+ // {
+ // PRINTF("Error: Failed to enable SC_R_I2C_1 clock \r\n");
+ // }
- if (sc_pm_set_clock_rate(ipc, SC_R_I2C_1, SC_PM_CLK_PER, &src_rate) != SC_ERR_NONE)
- {
- PRINTF("Error: Failed to set SC_R_I2C_1 clock rate\r\n");
- }
+ // if (sc_pm_set_clock_rate(ipc, SC_R_I2C_1, SC_PM_CLK_PER, &src_rate) != SC_ERR_NONE)
+ // {
+ // PRINTF("Error: Failed to set SC_R_I2C_1 clock rate\r\n");
+ // }
INTMUX_Init(CM4__INTMUX);
IRQSTEER_Init(IRQSTEER);
④ --- a/boards/mekmimx8qx/demo_apps/rear_view_camera/app_srtm.c
+++ b/boards/mekmimx8qx/demo_apps/rear_view_camera/app_srtm.c
@@ -114,17 +114,17 @@ static struct _srtm_auto_adapter autoAdapter = {.registerEvent = APP_SRTM_Auto
.powerReport = APP_SRTM_Auto_PowerReport,
.getInfo = APP_SRTM_Auto_GetInfo};
-static struct _i2c_bus qx_i2c_buses[] = {{.bus_id = 1,
+static struct _i2c_bus qx_i2c_buses[] = {/*{.bus_id = 1,
.base_addr = ADMA__LPI2C1_BASE,
.type = SRTM_I2C_TYPE_LPI2C,
.switch_idx = I2C_SWITCH_NONE,
- .switch_channel = SRTM_I2C_SWITCH_CHANNEL_UNSPECIFIED},
+ .switch_channel = SRTM_I2C_SWITCH_CHANNEL_UNSPECIFIED},*/
{.bus_id = 5,
.base_addr = CM4__LPI2C_BASE,
.type = SRTM_I2C_TYPE_LPI2C,
.switch_idx = I2C_SWITCH_NONE,
.switch_channel = SRTM_I2C_SWITCH_CHANNEL_UNSPECIFIED},
- {.bus_id = 12,
+ /*{.bus_id = 12,
.base_addr = ADMA__LPI2C1_BASE,
.type = SRTM_I2C_TYPE_LPI2C,
.switch_idx = 0,
@@ -143,7 +143,7 @@ static struct _i2c_bus qx_i2c_buses[] = {{.bus_id = 1,
.base_addr = ADMA__LPI2C1_BASE,
.type = SRTM_I2C_TYPE_LPI2C,
.switch_idx = 0,
- .switch_channel = SRTM_I2C_SWITCH_CHANNEL3}};
+ .switch_channel = SRTM_I2C_SWITCH_CHANNEL3}*/};
static struct _i2c_switch qx_i2c_switchs[] = {
{.slaveAddr = EXAMPLE_I2C_SWITCH_ADDR, .cur_channel = SRTM_I2C_SWITCH_CHANNEL_UNSPECIFIED}};
@@ -481,9 +481,9 @@ static void APP_SRTM_InitI2CDevice(void)
{
lpi2c_master_config_t masterConfig;
- LPI2C_MasterGetDefaultConfig(&masterConfig);
- masterConfig.baudRate_Hz = EXAMPLE_IOEXP_LPI2C_BAUDRATE;
- LPI2C_MasterInit(EXAMPLE_IOEXP_LPI2C_MASTER, &masterConfig, I2C_SOURCE_CLOCK_FREQ_LPI2C1);
+ // LPI2C_MasterGetDefaultConfig(&masterConfig);
+ // masterConfig.baudRate_Hz = EXAMPLE_IOEXP_LPI2C_BAUDRATE;
+ // LPI2C_MasterInit(EXAMPLE_IOEXP_LPI2C_MASTER, &masterConfig, I2C_SOURCE_CLOCK_FREQ_LPI2C1);
LPI2C_MasterGetDefaultConfig(&masterConfig);
masterConfig.baudRate_Hz = EXAMPLE_LPI2C_BAUDRATE;
diff --git a/boards/mekmimx8qx/demo_apps/rear_view_camera/app_srtm.h b/boards/mekmimx8qx/demo_apps/rear_view_camera/app_srtm.h
index c341e97..69a7bae 100644
⑤ --- a/boards/mekmimx8qx/demo_apps/rear_view_camera/app_srtm.h
+++ b/boards/mekmimx8qx/demo_apps/rear_view_camera/app_srtm.h
@@ -39,9 +39,9 @@
#define EXAMPLE_LPI2C_BAUDRATE (400000) /*in i2c example it is 100000*/
#define I2C_SOURCE_CLOCK_FREQ_M4 CLOCK_GetIpFreq(kCLOCK_M4_0_Lpi2c) /*M4_LPI2C*/
-#define EXAMPLE_IOEXP_LPI2C_BAUDRATE (100000) /*in i2c example it is 100000*/
-#define EXAMPLE_IOEXP_LPI2C_MASTER ADMA__LPI2C1
-#define I2C_SOURCE_CLOCK_FREQ_LPI2C1 CLOCK_GetIpFreq(kCLOCK_DMA_Lpi2c1) /*ADMA_LPI2C1*/
+// #define EXAMPLE_IOEXP_LPI2C_BAUDRATE (100000) /*in i2c example it is 100000*/
+// #define EXAMPLE_IOEXP_LPI2C_MASTER ADMA__LPI2C1
+// #define I2C_SOURCE_CLOCK_FREQ_LPI2C1 CLOCK_GetIpFreq(kCLOCK_DMA_Lpi2c1) /*ADMA_LPI2C1*/
#define I2C_SWITCH_NONE 1 /*MAX SWITCH in this board is 1*/
2.3 修改 kernel 代碼
--- a/arch/arm64/boot/dts/freescale/imx8x-mek-rpmsg.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8x-mek-rpmsg.dtsi
@@ -3,15 +3,15 @@
/delete-node/ &cm40_i2c;
-/delete-node/ &i2c1;
+// /delete-node/ &i2c1;
-/ {
- aliases {
- i2c1 = &i2c_rpbus_1;
- };
-};
+// / {
+// aliases {
+// i2c1 = &i2c_rpbus_1;
+// };
+// };
-&i2c_rpbus_1 {
+&i2c1 {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
@@ -129,68 +161,68 @@
&i2c_rpbus_12 {
#address-cells = <1>;
#size-cells = <0>;
- status = "okay";
+ status = "disabled";
- max7322: gpio@68 {
- compatible = "maxim,max7322";
- reg = <0x68>;
- gpio-controller;
- #gpio-cells = <2>;
- };
+ // max7322: gpio@68 {
+ // compatible = "maxim,max7322";
+ // reg = <0x68>;
+ // gpio-controller;
+ // #gpio-cells = <2>;
+ // };
};
&i2c_rpbus_14 {
#address-cells = <1>;
#size-cells = <0>;
- status = "okay";
-
- fxos8700@1e {
- compatible = "fsl,fxos8700";
- reg = <0x1e>;
- interrupt-open-drain;
- };
-
- fxas2100x@21 {
- compatible = "fsl,fxas2100x";
- reg = <0x21>;
- interrupt-open-drain;
- };
+ status = "disabled";
- pressure-sensor@60 {
- compatible = "fsl,mpl3115";
- reg = <0x60>;
- interrupt-open-drain;
- };
+ // fxos8700@1e {
+ // compatible = "fsl,fxos8700";
+ // reg = <0x1e>;
+ // interrupt-open-drain;
+ // };
+
+ // fxas2100x@21 {
+ // compatible = "fsl,fxas2100x";
+ // reg = <0x21>;
+ // interrupt-open-drain;
+ // };
+
+ // pressure-sensor@60 {
+ // compatible = "fsl,mpl3115";
+ // reg = <0x60>;
+ // interrupt-open-drain;
+ // };
};
&i2c_rpbus_15 {
#address-cells = <1>;
#size-cells = <0>;
- status = "okay";
-
- pca9557_a: gpio@1a {
- compatible = "nxp,pca9557";
- reg = <0x1a>;
- gpio-controller;
- #gpio-cells = <2>;
- };
-
- pca9557_b: gpio@1d {
- compatible = "nxp,pca9557";
- reg = <0x1d>;
- gpio-controller;
- #gpio-cells = <2>;
- };
+ status = "disabled";
- isl29023@44 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_isl29023>;
- compatible = "fsl,isl29023";
- reg = <0x44>;
- rext = <499>;
- interrupt-parent = <&lsio_gpio1>;
- interrupts = <2 2>;
- };
+ // pca9557_a: gpio@1a {
+ // compatible = "nxp,pca9557";
+ // reg = <0x1a>;
+ // gpio-controller;
+ // #gpio-cells = <2>;
+ // };
+
+ // pca9557_b: gpio@1d {
+ // compatible = "nxp,pca9557";
+ // reg = <0x1d>;
+ // gpio-controller;
+ // #gpio-cells = <2>;
+ // };
+
+ // isl29023@44 {
+ // pinctrl-names = "default";
+ // pinctrl-0 = <&pinctrl_isl29023>;
+ // compatible = "fsl,isl29023";
+ // reg = <0x44>;
+ // rext = <499>;
+ // interrupt-parent = <&lsio_gpio1>;
+ // interrupts = <2 2>;
+ // };
};
&cm40_i2c_lpcg {
@@ -198,7 +230,7 @@
};
&i2c1_lpcg {
- status = "disabled";
+ status = "okay";
};
&can0_lpcg {
3. 測試結果
編譯燒錄上電後,使用 i2cdetect -l 可以看到 rpmsg i2c1 已經成功改為普通的 lpi2c1,如下所示:
以上為基於 i.MX8QXP Android Automotive12 把 RPMSG I2C1 改為 LPI2C!!!
參考文獻《Android_User's_Guide.pdf》
《Android_Quick_Start_Guide.pdf》
評論