I am trying to enable GPIO_IO16 as GPIO pins and then tiggle it using Zephyr RTOS on M Core. However, these pins are listed as SAI3 pins under A55’s control. How can I move the ownership of SAI3 from A to M core and then configure them as GPIO pins in Zephyr’s application/dts and then toggle it using zephyr.elf?
Hi, I’m the Toradex AI Assistant.
I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.
GPIO3_IO16 Configuration for Cortex-M Core
Based on the available documentation, there are specific considerations when working with GPIO3_IO16 on Toradex modules with Cortex-M cores.
Known Issue with GPIO3_IO16
There is a documented issue with GPIO3_IO16 on Verdin iMX8M Plus when using it from the Cortex-M core (1). The pin may appear to always read “low” even when voltage is applied, which suggests configuration conflicts in the device tree.
Root Cause Analysis
The issue stems from pin configuration conflicts in the device tree files (1). Specifically:
- GPIO3_IO16 (SODIMM_64) can be used for I2C3, USDHC3, or NAND functions
- The
pinctrl_flexspi0node inimx8mp-verdin.dtsiconfigures this pin for peripheral functions - Even when I2C3 is disabled, the pinctrl configuration may still interfere with GPIO functionality
Device Tree Configuration
The current configuration in the device tree shows (1):
&iomuxc {
pinctrl_flexspi0: flexspi0grp {
fsl,pins =
<MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK 0x1c2>, /* SODIMM 52 */
<MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B 0x82>, /* SODIMM 54 */
<MX8MP_IOMUXC_NAND_DQS__FLEXSPI_A_DQS 0x82>, /* SODIMM 66 */
<MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00 0x82>, /* SODIMM 56 */
<MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01 0x82>, /* SODIMM 58 */
<MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02 0x82>, /* SODIMM 60 */
<MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03 0x82>, /* SODIMM 62 */
<MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x82>; /* SODIMM 64 */
};
}
Workaround Solution
The documentation indicates that manual configuration within the Cortex-M program can work, but timing is critical (1):
- Early Configuration: If you configure GPIO3_IO16 at the very beginning of your Cortex-M program (started by u-boot), it works
- Late Configuration: If you configure it after Torizon OS has booted, the configuration is not overwritten
U-Boot Configuration Issue
There appears to be a mismatch between u-boot and Linux device tree configurations (1). The u-boot configuration may incorrectly set up the pin, which gets corrected later in the boot process.
Recommended Approach
For your Zephyr application on the M core:
- Configure the pin early in your Zephyr application initialization
- Ensure proper timing - configure after u-boot but before the full Linux boot process interferes
- Monitor the boot sequence to identify the optimal configuration window
Alternative Considerations
If GPIO3_IO16 continues to present issues, consider using other available GPIO pins that don’t have the same peripheral function conflicts documented in the device tree.
Note: The specific behavior may vary depending on your exact module version and software configuration. The timing-sensitive nature of this configuration suggests it’s related to the boot sequence and resource ownership between the A and M cores.
Best regards, Toradex AI Assistant.
I changed .cfg file on imx-system-manager: removed SAI3 from A55 Non secure and added it to M7’s resources, removed GPIO_IO16 from A55 and added under M7, and then rebuilt the image and flashed it. Then I configured the GPIO_IO16 in zephyr’s dts and wrote the application source code. running the west build command did not show any errors and successfully built and copied the zephyr.elf file to target. On running the elf file using remote proc, i can not observe the pin toggling.
Hello Deepshika Borundiya,
I think a good place to start would be to make sure not no use the pins on Linux, but configuring them on Zephyr.
You need to remove/disable in the Linux device tree and add to Zephyr device tree.
Let us know if this solves the issue of it persists.
Also, I think you are aware of this blog, but it may be relevant Loading Zephyr on iMX95 Cortex-M from Linux with OpenAMP
best regards
Maximiliano Zapata
Toradex
Hey Maximiliano.tx,
I disabled SAI3 pins on both Linux dts and zephyr dts. I also added the pinmux configuration for GPIO. Following is the overlay file created for zephyr:
/ {
aliases {
led0 = &user_led;
};
leds {
compatible = "gpio-leds";
/* USER LED on GPIO2 line 16 (GPIO_IO16) */
user_led: led_gpio_io16 {
gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>;
label = "USER_LED_IO16";
/* NOTE: gpio-leds child nodes do NOT allow pinctrl-* properties */
};
};
};
/\* Prevent GPIO1 (0x47400000) from probing on M7 \*/
&gpio1 {
status = “disabled”;
};
/\* Apply pin mux directly to the GPIO controller using the IOMUXC pin node \*/
&gpio2 {
status = “okay”;
/* This must point to the IOMUXC pin node (numeric pinmux array),
* NOT to a pinctrl "group".
*/
pinmux = <&iomuxc_gpio_io16_gpio_io_bit_gpio2_io_bit16>;
};
/\* Optional: keep SAI3 out of the way \*/
&sai3 {
status = “disabled”;
/delete-property/ pinctrl-0;
/delete-property/ pinctrl-names;
};
However, while loading zephyr.elf and running it using remoteproc (opamp), M7 is not able to configure the gpio (gpio_pin_configure_dt returns ENOTSUP).
Hello Deepshika Borundiya,
The issue looks related to Zephyr. Our suggestion to discard Linux interference is to load the firmware from u-boot.
If the issue persist, it is a matter of a Zephyr configuration, for which is best to check on their community/support channel
Let me know how that goes
best regards
Maximiliano Zapata
Toradex
Hello Deepshika Borundiya,
just checking in, was this resolved?
thanks
Maximiliano Zapata
Toradex