S32K344 SPI + DMA Lpspi_Ip_AsyncTransmitFast

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

S32K344 SPI + DMA Lpspi_Ip_AsyncTransmitFast

跳至解决方案
8,224 次查看
not_a_duck
Contributor III

This question might be similar to this one: https://community.nxp.com/t5/S32K/S32K312-LPSPI-DMA-AsyncTransmitFast/m-p/1923811 

I have to send two spi transaction to a device. I am trying to use Lpspi_Ip_AsyncTransmitFast.

const Lpspi_Ip_FastTransferType ft[] = {
    {
        .ExternalDevice = &Lpspi_Ip_DeviceAttributes_SpiExternalDevice_0_Instance_0,
        .TxBuffer = txbuf_wren,
        .RxBuffer = rxbuf_wren,
        .DefaultData = 0,
        .Length = 1,
        .KeepCs = false,
    },
    {
        .ExternalDevice = &Lpspi_Ip_DeviceAttributes_SpiExternalDevice_0_Instance_0,
        .TxBuffer = txbuf,
        .RxBuffer = rxbuf,
        .DefaultData = 0,
        .Length = 10,
        .KeepCs = false,
    }
};    

void send_spi_txn(void)
{
    Lpspi_Ip_StatusType status = Lpspi_Ip_AsyncTransmitFast( ft, 2, Lpspi_Ip_Callback_lpspi_0_dma );
    if (status != LPSPI_IP_STATUS_SUCCESS)
    {
        failed_spi_dma = true;
    }
}

 
I have already tested using Lpspi_Ip_AsyncTransmit to send a single transaction and then sending another one from the completion callback, but this is obviously not ideal so would like to be able to use the transferlist instead.

The issue is that no data is being sent. the first time Lpspi_Ip_AsyncTransmitFast is called it reports success, but every subsequent call fails. also can see that there are no spi transfers. on the logic analyzer, but when i just do Lpspi_Ip_AsyncTransmit everything works fine.

标记 (4)
0 项奖励
回复
1 解答
8,116 次查看
not_a_duck
Contributor III

Unfortunately I can't post the project because I am only using S32DS to configure the RTD and to generate driver config files.

But I was able to work through the issues and unsurprisingly it was a data cache issue with the DMA.

as for the setup issues:
  • didn't properly link the scatter gather channels. (each channel needs to link to the next one and last one needs to be marked as final)
  • didn't have the tx/rx dma channels priorities correctly (rx higher than tx)
  • didn't have the tx/rx dma channel complete interrupts prioritized correctly. (tx higher than rx)
and the data cache issue boiled down to the MemMap.h files.
nxp uses these defines:

 

#define MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#include "Mcl_MemMap.h"
/* Pointer to the DMA Initialization Configuration. Based on this configuration pointer, the DMA Driver obtains all information for the Logic Channels and corresponding Channel Configurations. The Pointer is loaded when Dma_Ip_Init() is called. */
static const Dma_Ip_InitType * Dma_Ip_pxInit;
#define MCL_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#include "Mcl_MemMap.h"
and in the <module_name>_MemMap.h they define what the compiler should do. in this case #pragma GCC section bss ".mcal_bss_no_cacheable"

 

#ifdef MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
/**
* @file Mcl_MemMap.h
*/
#undef MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#define ENTERED_MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#ifndef MEMMAP_MATCH_ERROR
#define MEMMAP_MATCH_ERROR
#else
#ifndef MCL_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#error "MemMap.h, no valid matching start-stop section defined."
#endif
#endif
/**
* @file Mcl_MemMap.h
*/
#undef MEMMAP_ERROR
#pragma GCC section bss ".mcal_bss_no_cacheable"
#endif
 

for gcc unless you use the gcc version that comes with the s32ds ide or download their specific version of gcc these types of pragmas aren't supported.
so for now i just went through all the rtd files that used dma and manually added the right section attributes to make them non-cacheable either .mcal_bss_no_cacheable or .mcal_data_no_cacheableso for the snippet above i had to add:
 
__attribute__((section(".mcal_bss_no_cacheable")))
static const Dma_Ip_InitType * Dma_Ip_pxInit;

i replaced all the <module_name>_MemMap.h with empty dummy files to make the compiler happy which means i have to manually add all the __attribute__((section())) compiler directives.

在原帖中查看解决方案

5 回复数
4,232 次查看
Ashin
Contributor II

Hello,

is there any further update on this topic? is there any example project available.

0 项奖励
回复
8,149 次查看
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @not_a_duck,

Could you share the project so that I can test it?

 

Thank you,

Daniel

 

0 项奖励
回复
8,117 次查看
not_a_duck
Contributor III

Unfortunately I can't post the project because I am only using S32DS to configure the RTD and to generate driver config files.

But I was able to work through the issues and unsurprisingly it was a data cache issue with the DMA.

as for the setup issues:
  • didn't properly link the scatter gather channels. (each channel needs to link to the next one and last one needs to be marked as final)
  • didn't have the tx/rx dma channels priorities correctly (rx higher than tx)
  • didn't have the tx/rx dma channel complete interrupts prioritized correctly. (tx higher than rx)
and the data cache issue boiled down to the MemMap.h files.
nxp uses these defines:

 

#define MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#include "Mcl_MemMap.h"
/* Pointer to the DMA Initialization Configuration. Based on this configuration pointer, the DMA Driver obtains all information for the Logic Channels and corresponding Channel Configurations. The Pointer is loaded when Dma_Ip_Init() is called. */
static const Dma_Ip_InitType * Dma_Ip_pxInit;
#define MCL_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#include "Mcl_MemMap.h"
and in the <module_name>_MemMap.h they define what the compiler should do. in this case #pragma GCC section bss ".mcal_bss_no_cacheable"

 

#ifdef MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
/**
* @file Mcl_MemMap.h
*/
#undef MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#define ENTERED_MCL_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#ifndef MEMMAP_MATCH_ERROR
#define MEMMAP_MATCH_ERROR
#else
#ifndef MCL_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
#error "MemMap.h, no valid matching start-stop section defined."
#endif
#endif
/**
* @file Mcl_MemMap.h
*/
#undef MEMMAP_ERROR
#pragma GCC section bss ".mcal_bss_no_cacheable"
#endif
 

for gcc unless you use the gcc version that comes with the s32ds ide or download their specific version of gcc these types of pragmas aren't supported.
so for now i just went through all the rtd files that used dma and manually added the right section attributes to make them non-cacheable either .mcal_bss_no_cacheable or .mcal_data_no_cacheableso for the snippet above i had to add:
 
__attribute__((section(".mcal_bss_no_cacheable")))
static const Dma_Ip_InitType * Dma_Ip_pxInit;

i replaced all the <module_name>_MemMap.h with empty dummy files to make the compiler happy which means i have to manually add all the __attribute__((section())) compiler directives.
8,194 次查看
not_a_duck
Contributor III

@PetrS or @davidtosenovjan do either of you have any suggestions on what i can check?

one additional thing i have noticed is that the dma interrupt for the tx channel is being called repeatedly. it is supposed to call Lpspi_Ip_LPSPI_0_IrqTxDmaHandler callback but it never does.
Screenshot 2024-09-09 at 4.11.50 PM.pngScreenshot 2024-09-09 at 4.11.45 PM.png

0 项奖励
回复
8,192 次查看
not_a_duck
Contributor III

correction: `Lpspi_Ip_LPSPI_0_IrqTxDmaHandler` actually does get called but only once. and then never again

0 项奖励
回复