S32K344 FlexIO I2C and DMA HardFault

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32K344 FlexIO I2C and DMA HardFault

377 Views
nehalp
Contributor III

I'm trying to use FlexIO I2C with DMA. Blocking transfers do work correctly, so I know polling mode is working. 

  • I am experiencing a HardFault when executing Flexio_I2c_Ip_MasterSendData.
    • I have traced this to when the following call executes in Dma_Ip.c:
      • /*Done shall be cleared before a new transfer is configured. */
      • HwAccDmaCh_SetCommand((uint32)DMA_IP_CH_CLEAR_DONE, LocHwVers, LocHwInst, LocHwCh);
    • This function calls hwv3AccInlineDmaCh_CmdClearDone, which seems to fail when attempting to write the DONE bit in the TCD_CH_CSR.
  • I have done my best to configure FlexIO, DMA, and DMA Mux per the RTD_I2C_UM, using only the low-level drivers.
  • I have verified that MC_ME is enabling the TCD clock registers during Clock_Ip_Init (and PRTN1_COFB0_STAT = 0xffffffff after Clock_Ip_Init())
  • DmaInit is able to execute hwv3AccInlineDmaCh_CmdClearDone successfully for all the DMA channels in use
  • I am able to send an initial (2-byte) I2C register write during my device init routine. This uses polling mode due to Size <= 2

FlexIO I2C is configured with "I2c DMA Used" and "I2c DMA Optimize Mode"

nehalp_0-1710871250994.png

DMA is configured with 3 channels (Tx, Rx, Timer), each with Global Config enabled at default values, and Tx and Timer configure with 3 and 4 Scatter/Gather lists each:

nehalp_1-1710871344356.png

Tx element 0 (dmaLogicChannelConfig_ScatterGatherArrayType_0) element link = /Dma_Ip/Dma/MclConfig/dmaLogicChannel_Type_3_FlexioI2cTx/dmaLogicChannel_ConfigType/dmaLogicChannel_ScatterGatherConfigType/dmaLogicChannelConfig_ScatterGatherArrayType_1

Tx element 1 (dmaLogicChannelConfig_ScatterGatherArrayType_1) element link = /Dma_Ip/Dma/MclConfig/dmaLogicChannel_Type_3_FlexioI2cTx/dmaLogicChannel_ConfigType/dmaLogicChannel_ScatterGatherConfigType/dmaLogicChannelConfig_ScatterGatherArrayType_2

(and so on, similarly for Timer)

nehalp_2-1710871557337.png

 

Rx only has a single Scatter/Gather element (though perhaps none is needed?)

nehalp_3-1710871613953.png

Am I missing some key configuration setting or initialization function call?

Tags (1)
0 Kudos
4 Replies

293 Views
nehalp
Contributor III

With the configuration changes to "add channel", I have been able to get Flexio I2C working with Optimize DMA. However, I think this patch is additionally needed, else the returned status is always a timeout (since it appears to check the wrong clock):

--- a/Flexio_I2c_Ip.c
+++ b/Flexio_I2c_Ip.c
@@ -1421,7 +1421,14 @@ static void Flexio_I2c_Ip_MasterCheckStatus(uint8 Instance,
 
     ResourceIndex = Master->FlexioCommon.ResourceIndex;
     boolean EscapeFunction = FALSE;
+    uint8 TimerScl;
 
+#if (STD_ON == FLEXIO_I2C_IP_DMA_OPTIMIZE_ENABLE)
+    TimerScl = Master->SclAddChannel;
+    (void)ResourceIndex;
+#else
+    TimerScl = SCL_TIMER(ResourceIndex);
+#endif
     /* Check for errors */
     if (Flexio_Mcl_Ip_GetShifterErrorStatus(BaseAddr, TX_SHIFTER(ResourceIndex)))
     {
@@ -1472,7 +1479,7 @@ static void Flexio_I2c_Ip_MasterCheckStatus(uint8 Instance,
         }
     }
     /* Check if the transfer is over */
-    if ((Flexio_Mcl_Ip_GetTimerStatus(BaseAddr, SCL_TIMER(ResourceIndex))) && (FALSE == EscapeFunction))
+    if ((Flexio_Mcl_Ip_GetTimerStatus(BaseAddr, TimerScl)) && (FALSE == EscapeFunction))
     {
         Master->EventCount--;
 
0 Kudos

350 Views
nehalp
Contributor III

Looks like the hard fault was due to the lack of "Enable User Mode Support" in the DMA module.

I also realized that Flexio for SCL and SDA each need a "Add Channel" configured. Now I'm able to see SCL toggle for a DMA transfer, but nothing on SDA.

 
 

 

0 Kudos

356 Views
nehalp
Contributor III

It looks like it is tripping over task privileges and MPU protections, even though the MPU appears to be configured to allow read/write access to the configuration register space, when trying to write to the DMA TCD from an unprivileged task, I see the hardfault. If I make the task privileged, there's no hardfault.

0 Kudos

368 Views
nehalp
Contributor III

Before Clock_Ip_Init() - MC_ME and TCD[4] registers:

nehalp_0-1710875654860.png

Immediately after stepping over Clock_Ip_Init(). You can see MC_ME has clocks enabled, and TCD is now readable:

nehalp_1-1710875736786.png

Successfully writing to TCD during DmaInit():

nehalp_2-1710875898588.png

Successful read during MasterSendData:

nehalp_3-1710876228452.png

HardFault:

nehalp_4-1710876336172.png

 

0 Kudos