TI中文支持网
TI专业的中文技术问题搜集分享网站

TDA4VM: mcusw的MCAL之多路MCU_MCSPI调试问题咨询

Part Number:TDA4VM

我使用了MCU_MCSPI0和MCU_MCSPI1分别对外接了两个外设。使用EB配置成异步中断模式。

使用mcsw中的mcal-spi驱动代码(ti-processor-sdk-rtos-j721e-evm-07_03_00_07)。

两路SPI配置如下:

MCU_MCSPI0 – seq0 – job0 – channel0 – 外设0

MCU_MCSPI1 – seq1 – job1 – channel1 – 外设1

调试发现问题,现象如下:

1. MCU_MCSPI0跟外设0通信都OK;(逻辑分析仪截取数据跟中断读取RAM数据都OK)

2. MCU_MCSPI1单独发送,逻辑分析仪截取发现没有数据发出;

3. 先发一包SPI0再发一包SPI1,SPI0数据OK,但是SPI1发送的数据是SPI0的,另外RAM读取数据都是0。

换种方法测试,将SPI0和SPI1的通道配置互换,即

MCU_MCSPI1 – seq0 – job0 – channel0 – 外设0

MCU_MCSPI0 – seq1 – job1 – channel1 – 外设1

测试结果是SPI1收发正常了,SPI0又出现了上面说明的异常情况。

以上调试结果分析,只有当外设配置的所有参数配置在第0的位置才好使,怀疑是MCAL源代码有问题,但也不排除是我的配置或者使用方法有问题。

请教下你们是否用MCAL的SPI代码调试过多路SPI,是否遇到以上的问题?

(注:1. 以上相关测试代码参照了MCAL examples中的McspiApp.c初始化及发送流程,但是examples中的官方测试代码只测试了一路SPI0对应一路chan0。 2. autosar配置文件是基于demo中的基础上使用EB修改配置的。)

Cherry Zhou:

您好我们已收到您的问题并升级到英文论坛,因感恩节假期,预计答复您的时间将稍晚。敬请谅解!

,

Andy Yau:

您好,请问针对以上问题英文论坛有更新吗,是否有反馈结果呢

,

Cherry Zhou:

抱歉回复晚了。

第二个序列 / 外设的配置似乎不太对。 交换 SPI0/SPI1 实例说明SPI 模块及其初始化是正常的,但 SEQ1 编程不对。

根据TI的文档,目前还尚未测试多个 MCSPI 实例配置:

https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_DSP_ug_spi_top.html

您是否能够提供您用来测试两个 SPI 模块的code?

,

Andy Yau:

感谢回答!

对于上面问题我为了方面描述给简化了一下,其实我们SPI接了三个外设,SPI0分别用CS1和CS2接两个外设,SPI1用CS0接一个外设。

目前只调试SPI0的CS1对应的外设0,跟SPI1的CS0对应的外设2。外设0跟外设2同时发送。

发送接口:

Std_ReturnType SpiWrapper_Xfer(Spi_ChanIdType channelId,Spi_DataBufferType* SrcDataBufferPtr,Spi_DataBufferType* DesDataBufferPtr,Spi_NumberOfDataType Length)
{Spi_StatusTypestatus;uint32index;Spi_SequenceTypeseqId;Std_ReturnTyperetVal;const Spi_ConfigType *cfgPtr = &SpiDriver;#if (SPI_HW_STATUS_API == STD_ON)/* SPI HW unit should be free now - check */for (index = 0U; index < cfgPtr->maxHwUnit; index++){status = Spi_GetHWUnitStatus(cfgPtr->hwUnitCfg[index].hwUnitId);if(status != SPI_IDLE){return status;DRV_SPI_DBG("\x1b[1;31m[%s:%d]%d: HWUnitStatus is not idle!!\x1b[0m\n", __func__,__LINE__,OsWrapper_GetTimeMs());}}#endif/* #if (SPI_HW_STATUS_API == STD_ON) *//* Start the TX/RX */seqId= Spi_SeqConfig_PC[channelId].seqId;retVal= Spi_SetupEB(seqId,(Spi_DataBufferType*)SrcDataBufferPtr,(Spi_DataBufferType*)DesDataBufferPtr,Length);if (retVal != E_OK){DRV_SPI_DBG("\x1b[1;31m[%s:%d]%d: SPI Setup EB Failed!!\x1b[0m\n", __func__,__LINE__,OsWrapper_GetTimeMs());}retVal = Spi_AsyncTransmit(seqId);if (retVal != E_OK){DRV_SPI_DBG("\x1b[1;31m[%s:%d]%d: SPI Async transmit Failed!!\x1b[0m\n", __func__,__LINE__,OsWrapper_GetTimeMs());}return retVal;
}

下面是autosar配置生成的文件:

Spi_PBcfg.c:

CONST(struct Spi_ConfigType_s, SPI_CONFIG_DATA) SpiDriver =
{.maxChannels = 3U,.maxJobs = 3U,.maxSeq= 3U,.maxHwUnit = 2U,.maxExtDevCfg = 3U,.udmaInstId= (uint32)UDMA_INST_ID_MCU_0,.cacheWbInv = (Spi_CacheWbInv)SpiApp_wbInvCache,.cacheWb = (Spi_CacheWb)SpiApp_wbCache,.cacheInv = (Spi_CacheInv)SpiApp_invCache,.channelCfg ={[0] ={.channelBufType = SPI_EB,.dataWidth = 8U,.defaultTxData = 255U,.maxBufLength = 256U,.transferType = SPI_MSB,},[1] ={.channelBufType = SPI_EB,.dataWidth = 8U,.defaultTxData = 255U,.maxBufLength = 256U,.transferType = SPI_MSB,},[2] ={.channelBufType = SPI_EB,.dataWidth = 8U,.defaultTxData = 255U,.maxBufLength = 256U,.transferType = SPI_MSB,},},.jobCfg ={[0] ={.jobPriority = SPI_JOB_PRIORITY_0,.hwUnitId = SPI_UNIT_MCU_MCSPI0,.Spi_JobEndNotification = SpiApp_McuMcspiJob0EndNotification,.channelPerJob = 1U,.channelList ={[0] = 0U,},},[1] ={.jobPriority = SPI_JOB_PRIORITY_0,.hwUnitId = SPI_UNIT_MCU_MCSPI0,.Spi_JobEndNotification = SpiApp_McuMcspiJob1EndNotification,.channelPerJob = 1U,.channelList ={[1] = 1U,},},[2] ={.jobPriority = SPI_JOB_PRIORITY_0,.hwUnitId = SPI_UNIT_MCU_MCSPI1,.Spi_JobEndNotification = SpiApp_McuMcspiJob2EndNotification,.channelPerJob = 1U,.channelList ={[2] = 2U,},},},.seqCfg ={[0] ={.seqInterruptible = (uint8) FALSE,.Spi_SequenceEndNotification = SpiApp_McuMcspiSeq0EndNotification,.jobPerSeq = 1U,.jobList ={0U,},},[1] ={.seqInterruptible = (uint8) FALSE,.Spi_SequenceEndNotification = SpiApp_McuMcspiSeq1EndNotification,.jobPerSeq = 1U,.jobList ={1U,},},[2] ={.seqInterruptible = (uint8) FALSE,.Spi_SequenceEndNotification = SpiApp_McuMcspiSeq2EndNotification,.jobPerSeq = 1U,.jobList ={2U,},},},.hwUnitCfg ={[0] ={.hwUnitId = SPI_UNIT_MCU_MCSPI0,.enabledmaMode = (boolean)FALSE,.dmaTxChIntrNum = 0,.dmaRxChIntrNum = 0,},[1] ={.hwUnitId = SPI_UNIT_MCU_MCSPI1,.enabledmaMode = (boolean)FALSE,.dmaTxChIntrNum = 0,.dmaRxChIntrNum = 0,},},.extDevCfg ={[0] ={.mcspi ={.csEnable = (uint16) TRUE,.csMode= SPI_SINGLE,.csPolarity = SPI_LOW,.csIdleTime = SPI_DATADELAY_2,.clkDivider = 48U,.clkMode = SPI_CLK_MODE_1,.txRxMode= SPI_TX_RX_MODE_BOTH,.startBitEnable =(uint16) FALSE,.startBitLevel= SPI_LOW,.receptionLineEnable= DATA_LINE_1_RECEPTION,.transmissionLineEnable= DATA_LINE_0_TRANSMISSION,},},[1] ={.mcspi ={.csEnable = (uint16) TRUE,.csMode= SPI_SINGLE,.csPolarity = SPI_LOW,.csIdleTime = SPI_DATADELAY_2,.clkDivider = 96U,.clkMode = SPI_CLK_MODE_1,.txRxMode= SPI_TX_RX_MODE_BOTH,.startBitEnable =(uint16) FALSE,.startBitLevel= SPI_LOW,.receptionLineEnable= DATA_LINE_1_RECEPTION,.transmissionLineEnable= DATA_LINE_0_TRANSMISSION,},},[2] ={.mcspi ={.csEnable = (uint16) TRUE,.csMode= SPI_CONTINUOUS,.csPolarity = SPI_LOW,.csIdleTime = SPI_DATADELAY_2,.clkDivider = 48U,.clkMode = SPI_CLK_MODE_1,.txRxMode= SPI_TX_RX_MODE_BOTH,.startBitEnable =(uint16) FALSE,.startBitLevel= SPI_LOW,.receptionLineEnable= DATA_LINE_1_RECEPTION,.transmissionLineEnable= DATA_LINE_0_TRANSMISSION,},},},
};

Spi_Cfg.c:

CONST(Spi_ChannelConfigType_PC, SPI_CONFIG_DATA) Spi_ChannelConfig_PC[3] =
{[0] ={.channelId = SpiConf_SpiChannel_SpiChannel_0,},[1] ={.channelId = SpiConf_SpiChannel_SpiChannel_1,},[2] ={.channelId = SpiConf_SpiChannel_SpiChannel_2,},
};CONST(Spi_JobConfigType_PC, SPI_CONFIG_DATA) Spi_JobConfig_PC[3] =
{[0] ={.jobId = SpiConf_SpiJob_SpiJob_0,.csPin = SpiConf_SpiExternalDevice_CS0,.externalDeviceCfgId = (uint8)0U,},[1] ={.jobId = SpiConf_SpiJob_SpiJob_1,.csPin = SpiConf_SpiExternalDevice_CS1,.externalDeviceCfgId = (uint8)1U,},[2] ={.jobId = SpiConf_SpiJob_SpiJob_2,.csPin = SpiConf_SpiExternalDevice_CS2,.externalDeviceCfgId = (uint8)2U,},
};CONST(Spi_SeqConfigType_PC, SPI_CONFIG_DATA) Spi_SeqConfig_PC[3] =
{[0] ={.seqId = SpiConf_SpiSequence_SpiSequence_0,},[1] ={.seqId = SpiConf_SpiSequence_SpiSequence_1,},[2] ={.seqId = SpiConf_SpiSequence_SpiSequence_2,},
};

Spi_Cfg.h

#define SPI_VARIANT_POST_BUILD	(STD_ON)/***\brief Pre Compile config macro name.*//** \brief Buffer mode - Internal or External or Both */
#define SPI_CHANNELBUFFERS(SPI_EB)/** \brief Internal Buffer length in bytes - applicable only for SPI_IB */
#define SPI_IB_MAX_LENGTH(0U)/** \brief Enable/disable SPI dev detect error */
#define SPI_DEV_ERROR_DETECT(STD_ON)/** \brief Enable/disable SPI job log */
#define SPI_JOB_LOG(STD_ON)/** \brief Maximum job log entries when logging is ON */
#define SPI_MAX_JOB_LOG(100U)/** \brief Enable/disable SPI DMA Support */
#define SPI_MAX_HW_DMA_UNIT(0U)/** \brief Enable/disable SPI DMA Support */
#define SPI_DMA_ENABLE(STD_OFF)/** Scalability levels*/
/** \brief Basic Synchronous functions */
#define SPI_LEVEL_0(0U)
/** \brief Basic Asynchronous functions */
#define SPI_LEVEL_1(1U)
/** \brief Synchronous and Asynchronous functions */
#define SPI_LEVEL_2(2U)/** \brief Concurrent sync transmit support - by defualt this is off */
#define SPI_SUPPORT_CONCURRENT_SYNC_TRANSMIT(STD_OFF)/** \brief Scalability level */
#define SPI_SCALEABILITY(SPI_LEVEL_1)/** \brief Enable/disable SPI get version info API */
#define SPI_VERSION_INFO_API(STD_ON)/** \brief Enable/disable SPI HW Status API */
#define SPI_HW_STATUS_API(STD_ON)/** \brief Enable/disable SPI cancel API */
#define SPI_CANCEL_API(STD_ON)/** All below macros are used for static memory allocation and can be changed to* match the usecase requirements.*/
/** \brief Maximum channels allowed per job */
#define SPI_MAX_CHANNELS_PER_JOB(3U)/** \brief Maximum jobs allowed per sequence */
#define SPI_MAX_JOBS_PER_SEQ(3U)/** \brief Maximum channels across all jobs/sequence/hwunit */
#define SPI_MAX_CHANNELS(3U)/** \brief Maximum jobs across all sequence/hwunit */
#define SPI_MAX_JOBS(3U)/** \brief Maximum sequence across all hwunit */
#define SPI_MAX_SEQ(3U)/***\brief Maximum HW unit - This should match the sum for the below units ISR*which are ON.*/
#define SPI_MAX_HW_UNIT(8U)/***\brief Maximum external device cfg*/
#define SPI_MAX_EXT_DEV(11U)/*All below macros are used for enabling the ISR for a particular hardware.*//** \brief Enable/disable SPI MCU MCSPI0 unit ISR */#define SPI_UNIT_MCU_MCSPI0_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCU MCSPI1 unit ISR */#define SPI_UNIT_MCU_MCSPI1_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCU MCSPI2 unit ISR */#define SPI_UNIT_MCU_MCSPI2_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCSPI0 unit ISR */#define SPI_UNIT_MCSPI0_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCSPI1 unit ISR */#define SPI_UNIT_MCSPI1_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCSPI2 unit ISR */#define SPI_UNIT_MCSPI2_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCSPI3 unit ISR */#define SPI_UNIT_MCSPI3_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCSPI4 unit ISR */#define SPI_UNIT_MCSPI4_ACTIVE(STD_ON)/** \brief Enable/disable SPI MCSPI5 unit ISR */#define SPI_UNIT_MCSPI5_ACTIVE(STD_OFF)/** \brief Enable/disable SPI MCSPI6 unit ISR */#define SPI_UNIT_MCSPI6_ACTIVE(STD_OFF)/** \brief Enable/disable SPI MCSPI7 unit ISR */#define SPI_UNIT_MCSPI7_ACTIVE(STD_OFF)/** \brief ISR type */
#define SPI_ISR_TYPE(SPI_ISR_CAT1)/** \brief OS counter ID - used for timeout in case of error */
#define SPI_OS_COUNTER_ID((CounterType)OsCounter_0)/***\brief SPI timeout - used in McSPI IP reset*Each tick is 31.25us (for 32K Counter). Wait for 100ms which comes to*below value*/
#define SPI_TIMEOUT_DURATION(32000U)/** \brief Enable/disable SPI register read back API */
#define SPI_REGISTER_READBACK_API(STD_ON)/** \brief Symbolic Name Channel Id- 0 SpiChannel_0 */
#define SpiConf_SpiChannel_SpiChannel_0(0U)
/** \brief Symbolic Name Channel Id- 1 SpiChannel_1 */
#define SpiConf_SpiChannel_SpiChannel_1(1U)
/** \brief Symbolic Name Channel Id- 2 SpiChannel_2 */
#define SpiConf_SpiChannel_SpiChannel_2(2U)/** \brief Symbolic Name Chip Select- 0 */
#define SpiConf_SpiExternalDevice_CS0 (SPI_CS1)/** \brief Symbolic Name Job Id - 0 SpiJob_0 */
#define SpiConf_SpiJob_SpiJob_0(0U)/** \brief Symbolic Name Chip Select- 1 */
#define SpiConf_SpiExternalDevice_CS1 (SPI_CS2)/** \brief Symbolic Name Job Id - 1 SpiJob_1 */
#define SpiConf_SpiJob_SpiJob_1(1U)/** \brief Symbolic Name Chip Select- 2 */
#define SpiConf_SpiExternalDevice_CS2 (SPI_CS0)/** \brief Symbolic Name Job Id - 2 SpiJob_2 */
#define SpiConf_SpiJob_SpiJob_2(2U)/** \brief Symbolic Name Sequence Id - 0 SpiSequence_0 */
#define SpiConf_SpiSequence_SpiSequence_0(0U)
/** \brief Symbolic Name Sequence Id - 1 SpiSequence_1 */
#define SpiConf_SpiSequence_SpiSequence_1(1U)
/** \brief Symbolic Name Sequence Id - 2 SpiSequence_2 */
#define SpiConf_SpiSequence_SpiSequence_2(2U)/** \brief Symbolic Name HW Unit - 0 */
#define SpiConf_SpiExternalDevice_HwUnitId0(CSIB0)
/** \brief Symbolic Name HW Unit - 1 */
#define SpiConf_SpiExternalDevice_HwUnitId0(CSIB0)
/** \brief Symbolic Name HW Unit - 2 */
#define SpiConf_SpiExternalDevice_HwUnitId1(CSIB1)/***\name SPI DEM Error codes to report**Pre-compile switches for enabling/disabling DEM events*@{*/
#define DemConf_DemEventParameter_SPI_DEM_NO_EVENT (0xFFFFU)
#define SPI_DEM_NO_EVENT DemConf_DemEventParameter_SPI_DEM_NO_EVENT#ifndef SPI_E_HARDWARE_ERROR
/** \brief Hardware failed */
#define SPI_E_HARDWARE_ERROR(DemConf_DemEventParameter_SPI_E_HARDWARE_ERROR)
#endif/* @} *//* ========================================================================== */
/*Structures and Enums*/
/* ========================================================================== *//** \briefCache write-back invalidate function */
extern void SpiApp_wbInvCache(uint8 *buf, uint16 len);
/** \brief Cache write-back function */
extern void SpiApp_wbCache(uint8 *buf, uint16 len);
/** \brief Cache invalidate function */
extern void SpiApp_invCache(uint8 *buf, uint16 len);/** \brief SPI Configuration struct declaration */
extern const struct Spi_ConfigType_s SpiDriver;/** \brief SPI Channel PC Configuration struct declaration */
extern const struct Spi_ChannelConfigType_PC_s Spi_ChannelConfig_PC[SPI_MAX_CHANNELS];/** \brief SPI Job PC Configuration struct declaration */
extern const struct Spi_JobConfigType_PC_s Spi_JobConfig_PC[SPI_MAX_JOBS];/** \brief SPI Sequence PC Configuration struct declaration */
extern const struct Spi_SeqConfigType_PC_s Spi_SeqConfig_PC[SPI_MAX_SEQ];

测试两个SPI模块就是调用上面的SpiWrapper_Xfer接口,定义全局TX和RX buffer,传入channel。大致如下:

SpiWrapper_Xfer(0, TxBuffer0, RxBuffer0, 8);

SpiWrapper_Xfer(2, TxBuffer2, RxBuffer2, 8);

逻辑分析仪截取SPI总线数据,TxBuffer0、RxBuffer0正常,SpiApp_McuMcspiSeq0EndNotification中读取的数据也正常。

异常的是TxBuffer2发的竟然是TxBuffer0的数据!

然后SpiApp_McuMcspiSeq2EndNotification中读取RxBuffer2的数据都是0,但是逻辑分析仪截取数据看RX是有数据的。

以上,看看能否帮忙分析出问题点。

另外我对您的回复“第二个序列 / 外设的配置似乎不太对。”这句话不太理解,是说我的配置不对吗?

跟上面的稍有不同,详细配置如下:

MCU_MCSPI0 – CS1 – seq0 – job0 – channel0 – 外设0

MCU_MCSPI0 – CS2 – seq1 – job1 – channel1 – 外设1

MCU_MCSPI1 – CS0 – seq2 – job2 – channel2 – 外设2

,

Andy Yau:

哈喽,chan2正常了。修改地方是把SPI0-CS2改为DIO控制,csmode设置为SINGLE。chan0的SPI0-CS1不实用DIO,csmode设置为CONTINOUS。但是还是只能先发chan0再发chan2才好使,先发chan2就会失败。

,

Cherry Zhou:

好的收到,已帮您把最新的情况跟进给工程师,如果有新的消息会尽快给到您。

赞(0)
未经允许不得转载:TI中文支持网 » TDA4VM: mcusw的MCAL之多路MCU_MCSPI调试问题咨询
分享到: 更多 (0)