This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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修改配置的。

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

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

  • 抱歉回复晚了。

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

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

    https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/07_03_00_07/exports/docs/mcusw/mcal_drv/docs/drv_docs/ug_spi_top.html#ug_spi_eg_top

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

  • 感谢回答!

    对于上面问题我为了方面描述给简化了一下,其实我们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_StatusType		status;
    	uint32              index;
    	Spi_SequenceType    seqId;
    	Std_ReturnType      retVal;
    	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                               */
    /* ========================================================================== */
    
    
    
    
    /** \brief  Cache 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

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

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