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.
Hi team,
Two peripherals are externally connected using MCU_MCSPI0 and MCU_MCSPI1. Use EB to configure for asynchronous interrupt mode.
Use the mcal-spi driver code from mcsw (ti-processor-sdk-rtos-j721e-evm-07_03_00_07).
The two SPI configurations are as follows:
MCU_MCSPI0 - seq0 - Job0 - Channel0 - Peripheral 0
MCU_MCSPI1 - seq1 - Job1 - Channel1 - Peripheral 1
Issues:
1. MCU_MCSPI0 communication with peripheral 0 is OK; (logic analyzer captures data and interrupts reads RAM data both are OK).
2. MCU_MCSPI1 sent separately, logic analyzer intercept found no data was sent.
3. sent one packet SPI0 followed by one packet SPI1, and SPI0 data is OK, but SPI1 sends data for SPI0, and RAM reads are 0.
Then the customer tried another way for testing:
MCU_MCSPI1 - seq0 - Job0 - Channel0 - Peripheral 0
MCU_MCSPI0 - seq1 - Job1 - Channel1 - Peripheral 1
SPI1 transmit and receive is normal, but SPI0 has the issue described above again.
Only if all parameters of the peripheral configuration are configured in position 0, the result is normal. The customer suspected there is some thing wrong of MCAL source code.
The customer would like to ask if TI have debugged the overpass SPI with the SPI code from the McAL and encountered the above questions.
NOTE: 1. The above related test code refers to the McSpiApp.c initialization and transmission process in the McCall examples, but the official test code in the examples only tests one SPI0 for one chan0.
2. The autostar configuration file is modified using EB based on the basis in demo.
Could you help check this case? Thanks.
Best Regards,
Cherry
Hi,
It seems that something is wrong with the configuration of the second sequence/peripheral. Swapping the SPI0/SPI1 instances shows that the SPI modules and their initialization is fine, but there is something wrong with the seq1 programming.
According to our documentation, we have not tested multiple MCSPI instances configuration:
Would you be able to provide the code you are using to test the two SPI modules?
Regards,
Erick
Hi Erick,
Thanks for your support!
The SPI connects three peripherals, SPI0 uses CS1 and CS2 to connect two peripherals, SPI1 uses CS0 to connect to a peripheral. Currently only debug peripheral 0 for CS1 of SPI0, and peripheral 2 for CS0 of SPI1. Peripheral 0 is sent at the same time as Peripheral 2.
Transmit Interface:
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; }
Files generated by the autostar configuration:
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];
The two SPI modules are tested by calling the SpiWrapper_Xfer interface above to define the global TX and RX buffer, then pass into the channel, just as follows:
SpiWrapper_Xfer(0, TxBuffer0, RxBuffer0, 8);
SpiWrapper_Xfer(2, TxBuffer2, RxBuffer2, 8);
The logic analyzer captures SPI bus data, TxBUFFER0, RxBUFFER0 are OK, and the data read in SpiApp_McuMcspiSeq0EndNotification is also OK.
The point is TxBUFFER2 sends TxBUFFER0's data. The data read for RxBuffer2 in SpiApp_McpuMcspiSeq2EndNotification is 0. But the logic analyzer did can capture the data.
It seems that something is wrong with the configuration of the second sequence/peripheral.
Could you specify this? is there anything wrong with the configuration?
The detailed configuration is as follows:
MCU_MCSPI0 - CS1 - seq0 - job0 - channel0 - Peripheral 0
MCU_MCSPI0 - CS2 - seq1 - job1 - channel1 - Peripheral 1
MCU_MCSPI1 - CS0 - seq2 - job2 - channel2 - Peripheral 2
Thanks and Best Regards,
Cherry
Hi,
May I know is there any updates? There are also some new info:
Chan2 is working. Changed SPI0-CS2 to DIO control and csmode to SINGLE. SPI0-CS1 for chan0 does not use DIO and csmode is set to CONTINOUS. However, it can only start Chan0 and then Chan2, otherwise it will fail.
Thanks and Best Regards,
Cherry