Verdin IMX8MM, hardfault when initializing UART on M4 core

Hi @vix and @Jorn,

Good news, I was able to change from UART4 to UART3 (which is the UART2 of the board), only changing the Cortex-M code. It turns out I was missing the new clock config.

Here is the patch:

diff --git a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.c b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.c
index 2228b55..832015d 100644
--- a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.c
+++ b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.c
@@ -24,7 +24,7 @@
 void BOARD_InitDebugConsole(void)
 {
     uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
-    CLOCK_EnableClock(kCLOCK_Uart4);
+    CLOCK_EnableClock(kCLOCK_Uart3);
     DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
 }
 /* Initialize MPU, configure non-cacheable memory */
diff --git a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.h b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.h
index cee60e1..0b9ca6c 100644
--- a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.h
+++ b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/board.h
@@ -19,13 +19,13 @@
 /* The UART to use for debug messages. */
 #define BOARD_DEBUG_UART_TYPE     kSerialPort_Uart
 #define BOARD_DEBUG_UART_BAUDRATE 115200u
-#define BOARD_DEBUG_UART_BASEADDR UART4_BASE
-#define BOARD_DEBUG_UART_INSTANCE 4U
+#define BOARD_DEBUG_UART_BASEADDR UART3_BASE
+#define BOARD_DEBUG_UART_INSTANCE 3U
 #define BOARD_DEBUG_UART_CLK_FREQ                                                           \
-    CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootUart4)) / \
-        (CLOCK_GetRootPostDivider(kCLOCK_RootUart4)) / 10
-#define BOARD_UART_IRQ         UART4_IRQn
-#define BOARD_UART_IRQ_HANDLER UART4_IRQHandler
+    CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootUart3)) / \
+        (CLOCK_GetRootPostDivider(kCLOCK_RootUart3)) / 10
+#define BOARD_UART_IRQ         UART3_IRQn
+#define BOARD_UART_IRQ_HANDLER UART3_IRQHandler
 
 #define GPV5_BASE_ADDR        (0x32500000)
 #define FORCE_INCR_OFFSET     (0x4044)
diff --git a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/clock_config.c b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/clock_config.c
index eb851c1..d4e5826 100644
--- a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/clock_config.c
+++ b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/clock_config.c
@@ -99,8 +99,8 @@ void BOARD_BootClockRUN(void)
     //    CLOCK_SetRootDivider(kCLOCK_RootAxi, 1U, 2);
     //    CLOCK_SetRootMux(kCLOCK_RootAxi, kCLOCK_AxiRootmuxSysPll1); /* switch AXI to SYSTEM PLL1 800MHZ */
 
-    CLOCK_SetRootMux(kCLOCK_RootUart4, kCLOCK_UartRootmuxSysPll1Div10); /* Set UART source to SysPLL1 Div10 80MHZ */
-    CLOCK_SetRootDivider(kCLOCK_RootUart4, 1U, 1U);                     /* Set root clock to 80MHZ/ 1= 80MHZ */
+    CLOCK_SetRootMux(kCLOCK_RootUart3, kCLOCK_UartRootmuxSysPll1Div10); /* Set UART source to SysPLL1 Div10 80MHZ */
+    CLOCK_SetRootDivider(kCLOCK_RootUart3, 1U, 1U);                     /* Set root clock to 80MHZ/ 1= 80MHZ */
 
     CLOCK_EnableClock(kCLOCK_Rdc); /* Enable RDC clock */
     /* The purpose to enable the following modules clock is to make sure the M4 core could work normally when A53 core
diff --git a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/hello_world.c b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/hello_world.c
index d1f35d9..3fb5d77 100644
--- a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/hello_world.c
+++ b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/hello_world.c
@@ -29,8 +29,6 @@
  */
 int main(void)
 {
-    char ch;
-
     /* Init board hardware. */
     /* Board specific RDC settings */
     BOARD_RdcInit();
@@ -40,11 +38,14 @@ int main(void)
     BOARD_InitDebugConsole();
     BOARD_InitMemory();
 
-    PRINTF("hello world.\r\n");
+    uint8_t counter = 0;
+    int i;
 
     while (1)
     {
-        ch = GETCHAR();
-        PUTCHAR(ch);
+        if (counter == 0xff) counter = 0;
+        else counter++;
+        PRINTF("hello_world %d\r\n", counter);
+        for (i = 0; i < 10000000; i++);
     }
 }
diff --git a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/pin_mux.c b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/pin_mux.c
index b7f21c6..6572cd5 100644
--- a/boards/evkmimx8mm/demo_apps/hello_world_change_uart/pin_mux.c
+++ b/boards/evkmimx8mm/demo_apps/hello_world_change_uart/pin_mux.c
@@ -55,12 +55,12 @@ BOARD_InitPins:
  *
  * END ****************************************************************************************************************/
 void BOARD_InitPins(void) {                                /*!< Function assigned for the core: Cortex-M4[m4] */
-    IOMUXC_SetPinMux(IOMUXC_UART4_RXD_UART4_RX, 0U);
-    IOMUXC_SetPinConfig(IOMUXC_UART4_RXD_UART4_RX, 
+    IOMUXC_SetPinMux(IOMUXC_ECSPI1_MOSI_UART3_RX, 0U);
+    IOMUXC_SetPinConfig(IOMUXC_ECSPI1_MOSI_UART3_RX,
                         IOMUXC_SW_PAD_CTL_PAD_DSE(6U) |
                         IOMUXC_SW_PAD_CTL_PAD_FSEL(2U));
-    IOMUXC_SetPinMux(IOMUXC_UART4_TXD_UART4_TX, 0U);
-    IOMUXC_SetPinConfig(IOMUXC_UART4_TXD_UART4_TX, 
+    IOMUXC_SetPinMux(IOMUXC_ECSPI1_MOSI_UART3_TX, 0U);
+    IOMUXC_SetPinConfig(IOMUXC_ECSPI1_MOSI_UART3_TX,
                         IOMUXC_SW_PAD_CTL_PAD_DSE(6U) |
                         IOMUXC_SW_PAD_CTL_PAD_FSEL(2U));
 }

So a couple of things to notice: I created a new project called hello_world_change_uart, copied hello_world from NXP, and then I applied this patch. Also, I’ve changed the hello_word.c a little bit to keep printing “hello world” on my screen.

Please note the most important things: configuring the right clock to use the base UART3 and also changing the pin to the correct name. All pin names are available on the pin_mux files from the SDK (should be inside the hello_world project).

In my case, I wanted to use UART2 from the Verdin Development Board (SODIMM_139 or UART_2_TXD). Note that this pin routes to ECSPI1_MOSI UART3:

image

That’s why I changed to code to UART3 but I’m connected to UART2 of my board:

I loaded the code with u-boot and it just worked. I can see the messages being printed and I can also boot Linux without problems. Keep in mind that it’s recommended to disable this UART to prevent errors on the Linux side.

I’ve used the reference multimedia image 6.3 on my verdin Mini. I’ll now test it on TorizonCore, but I believe it will also work. @vix although this is for Verdin Mini, it should be the same procedure for the Verdin Plus.

Hope this helps, let me know if you have any questions.

Best Regards,
Hiago.

1 Like