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.
I have a requirement to interface TMS320F280025C with another controller over SPI interface. 280025C is configured as SPI slave. I have used SPI example 4 that uses DMA controller with SPI TX and RX buffers. The DMA is set for burst size of 8 and transfer size of 4. So 32 words make one complete transaction. I have disabled the internal loop back so that SPI receives data externally. Initially I tested by sending stream of data (32 16-bit words) using SPIA interface. The controller receives and prints data without any errors. As a next step I modified the same code for SPIB interface. Keeping the rest of the code same only the pinMux settings were updated for SPIB and DMA channels were assigned to SPIB instead of SPIA. However the SPIB interface is giving a lot of errors in the receive data. For e.g. if I am sending a constant value of 2 repeatedly 32 times then the data received in the SPIB buffer is as below:
DMA:2 2 2 258 2 1 2 2 2 0 2
2 2 2 0 2 258 2 2 2 2
2 258 1 7 2 2 2 0 2 2
2
DMA:2 2 2 2 0 2 2 2 0 2 2
2 1 2 2 2 2 2 0 2 2
58 2 0 2 2 2 3 2 2 2 2
2
DMA:2 2 6 2 2 2 2 0 0 2 2
6 1 2 2 2 0 2 2 2 2
0 2 2 2 6 2 2 2 2 0
2
The red values are in error. I don't suspect any issue with the transmission controller as SPIA interface reads data correctly. I have tested SPIB interface without DMA using FIFO interrupt but the results are same. I have spent more than 2 days to figure this issue but all in vain. I suspect there could be any silicon issue in SPIB?. Please check and let me know if I need to correct something.
Asad,
SPIB is validated as much as SPIA. There is a very remote chance that this could be a silicon issue. From your description, all I see is you incorrectly get SPIB RX data sporadically. I would difficult for me to guess what could be the problem. Will you be able to share your code both master and slave? What is your SPI Master?
Regards,
Manoj
Dear Manoj,
Thank you very much for initial thought sharing. To add more information, I am using TMS320F280025C launch pad as SPI slave. For the master side, I am using Arduino Due. The arduino code is very simple and is working fine with SPIA. It is given as below:
//############################################################################# // // FILE: spi_ex4_loopback_dma.c // // TITLE: SPI Digital Loopback with DMA // //! \addtogroup driver_example_list //! <h1>SPI Digital Loopback with DMA</h1> //! //! This program uses the internal loopback test mode of the SPI module. Both //! DMA interrupts and the SPI FIFOs are used. When the SPI transmit FIFO has //! enough space (as indicated by its FIFO level interrupt signal), the DMA //! will transfer data from global variable sData into the FIFO. This will be //! transmitted to the receive FIFO via the internal loopback. //! //! When enough data has been placed in the receive FIFO (as indicated by its //! FIFO level interrupt signal), the DMA will transfer the data from the FIFO //! into global variable rData. //! //! When all data has been placed into rData, a check of the validity of the //! data will be performed in one of the DMA channels' ISRs. //! //! \b External \b Connections \n //! - None //! //! \b Watch \b Variables \n //! - \b sData - Data to send //! - \b rData - Received data //! // //############################################################################# // $TI Release: F28002x Support Library v3.04.00.00 $ // $Release Date: Fri Feb 12 18:58:34 IST 2021 $ // $Copyright: // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //########################################################################### // // Included Files // #include "driverlib.h" #include "device.h" // // Defines // #define FIFO_LVL 8 // FIFO interrupt level #define BURST FIFO_LVL // Each burst will empty the FIFO #define TRANSFER 4 // It will take 4 bursts of 8 to transfer // all data in rData // // Globals // uint16_t sData[32]; // Send data buffer uint16_t rData[32]; // Receive data buffer uint16_t ascii[10]={0}; const uint16_t DMA_char[6]={'\r','\n','D','M','A',':'}; // Place buffers in GSRAM #pragma DATA_SECTION(sData, "ramgs0"); #pragma DATA_SECTION(rData, "ramgs0"); volatile uint16_t done = 0; // Flag to set when all data transfered volatile uint16_t count=0; // // Function Prototypes void configGPIOs(void); void initDMA(void); void initSPIFIFO(void); void initSCI(void); int int_to_char(int); __interrupt void dmaCh5ISR(void); __interrupt void dmaCh6ISR(void); // // Main // void main(void) { uint16_t i; // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pullups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Interrupts that are used in this example are re-mapped to ISR functions // found within this file. // Interrupt_register(INT_DMA_CH5, &dmaCh5ISR); Interrupt_register(INT_DMA_CH6, &dmaCh6ISR); //Configuring pins configGPIOs(); // // Set up DMA for SPI use, initialize the SPI for FIFO mode // initDMA(); initSPIFIFO(); // Setup SCI for debugging purpose initSCI(); // // Initialize the data buffers // for(i = 0; i < 32; i++) { sData[i] = 256+i; rData[i]= 0; } // // Enable interrupts required for this example // Interrupt_enable(INT_DMA_CH5); Interrupt_enable(INT_DMA_CH6); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; GPIO_writePin(DEVICE_GPIO_PIN_LED1,0); GPIO_writePin(DEVICE_GPIO_PIN_LED2,0); // // Start the DMA channels // DMA_startChannel(DMA_CH6_BASE); DMA_startChannel(DMA_CH5_BASE); // // Wait until the DMA transfer is complete // while(1) { GPIO_togglePin(DEVICE_GPIO_PIN_LED1); DEVICE_DELAY_US(1000000); SCI_writeCharArray(SCIA_BASE,DMA_char,6); for(i=0;i<32;i++) { count=int_to_char(rData[i]); SCI_writeCharArray(SCIA_BASE,ascii,count); SCI_writeCharBlockingFIFO(SCIA_BASE, '\t'); } SCI_writeCharBlockingFIFO(SCIA_BASE, '\r'); SCI_writeCharBlockingFIFO(SCIA_BASE, '\n'); } } // // Function to configure SPI A in FIFO mode. // void initSPIFIFO() { // // Must put SPI into reset before configuring it // SPI_disableModule(SPIB_BASE); // // FIFO configuration // SPI_enableFIFO(SPIB_BASE); SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_RXFF | SPI_INT_TXFF); SPI_setFIFOInterruptLevel(SPIB_BASE, (SPI_TxFIFOLevel)FIFO_LVL, (SPI_RxFIFOLevel)FIFO_LVL); // // SPI configuration. Use a 500kHz SPICLK and 16-bit word size. // SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_SLAVE, 1000000, 16); SPI_disableLoopback(SPIB_BASE); SPI_enableModule(SPIB_BASE); } // // DMA setup for both TX and RX channels. // void initDMA() { // // Initialize DMA // DMA_initController(); // // Configure DMA Ch5 for TX. When there is enough space in the FIFO, data // will be transferred from the sData buffer to the SPI module's transmit // buffer register. // DMA_configAddresses(DMA_CH5_BASE, (uint16_t *)(SPIB_BASE + SPI_O_TXBUF), sData); DMA_configBurst(DMA_CH5_BASE, BURST, 1, 0); DMA_configTransfer(DMA_CH5_BASE, TRANSFER, 1, 0); DMA_configMode(DMA_CH5_BASE, DMA_TRIGGER_SPIBTX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT); // // Configure DMA Ch5 interrupts // DMA_setInterruptMode(DMA_CH5_BASE, DMA_INT_AT_BEGINNING); DMA_enableInterrupt(DMA_CH5_BASE); DMA_enableTrigger(DMA_CH5_BASE); // // Configure DMA Ch6 for RX. When the FIFO contains at least 8 words to // read, data will be transferred from the SPI module's receive buffer // register to the rData buffer. // DMA_configAddresses(DMA_CH6_BASE, rData, (uint16_t *)(SPIB_BASE + SPI_O_RXBUF)); DMA_configBurst(DMA_CH6_BASE, BURST, 0, 1); DMA_configTransfer(DMA_CH6_BASE, TRANSFER, 0, 1); DMA_configMode(DMA_CH6_BASE, DMA_TRIGGER_SPIBRX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT); // // Configure DMA Ch6 interrupts // DMA_setInterruptMode(DMA_CH6_BASE, DMA_INT_AT_END); DMA_enableInterrupt(DMA_CH6_BASE); DMA_enableTrigger(DMA_CH6_BASE); } void initSCI(){ //mySCI0 initialization SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF | SCI_INT_TXFF | SCI_INT_FE | SCI_INT_OE | SCI_INT_PE | SCI_INT_RXERR | SCI_INT_RXRDY_BRKDT | SCI_INT_TXRDY); SCI_clearOverflowStatus(SCIA_BASE); SCI_resetTxFIFO(SCIA_BASE); SCI_resetRxFIFO(SCIA_BASE); SCI_resetChannels(SCIA_BASE); SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, (SCI_CONFIG_WLEN_8|SCI_CONFIG_STOP_ONE|SCI_CONFIG_PAR_NONE)); SCI_disableLoopback(SCIA_BASE); SCI_performSoftwareReset(SCIA_BASE); SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX0, SCI_FIFO_RX0); SCI_enableFIFO(SCIA_BASE); SCI_enableModule(SCIA_BASE); } // // DMA Channel 5 ISR // __interrupt void dmaCh5ISR(void) { DMA_stopChannel(DMA_CH5_BASE); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7); return; } // // DMA Channel 6 ISR // __interrupt void dmaCh6ISR(void) { uint16_t i; DMA_stopChannel(DMA_CH6_BASE); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7); // // Check for data integrity // //GPIO_writePin(DEVICE_GPIO_PIN_LED1,1); for(i = 0; i < 32; i++) { if (rData[i] != i) { // Something went wrong. rData doesn't contain expected data. GPIO_writePin(DEVICE_GPIO_PIN_LED2,1);//turn off green LED } } //Again triggering DMA transfer DMA_startChannel(DMA_CH6_BASE); DMA_startChannel(DMA_CH5_BASE); done = 1; return; } // // Configure GPIOs for external loopback. // void configGPIOs(void) { // // This test is designed for an external loopback between SPIA // and SPIB. // External Connections: // -GPIO40 and GPIO8 - SPISIMO // -GPIO41 and GPIO10 - SPISOMI // -GPIO22 and GPIO9 - SPICLK // -GPIO23 and GPIO11 - SPISTE // -GPIO31 is LED4 // -GPIO34 is LED5 GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1,GPIO_DIR_MODE_OUT);//setting LED1 pin as output GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED2,GPIO_DIR_MODE_OUT);//setting LED2 pin as output // // GPIO10 is the SPISOMIA. // /*GPIO_setPinConfig(GPIO_10_SPIB_SOMI); GPIO_setPadConfig(10, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(10, GPIO_QUAL_ASYNC); // // GPIO11 is the SPISIMO. // GPIO_setPinConfig(GPIO_11_SPIA_SIMO); GPIO_setPadConfig(11, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(11, GPIO_QUAL_ASYNC); // // GPIO09 is the SPICLKA. // GPIO_setPinConfig(GPIO_9_SPIA_CLK); GPIO_setPadConfig(9, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(9, GPIO_QUAL_ASYNC); // // GPIO5 is the SPISTEA. // GPIO_setPinConfig(GPIO_5_SPIA_STE); GPIO_setPadConfig(5, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(5, GPIO_QUAL_ASYNC);*/ // // GPIO40 is the SPISIMOB clock pin. // GPIO_setPinConfig(GPIO_40_SPIB_SIMO); GPIO_setPadConfig(40, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(40, GPIO_QUAL_ASYNC); // // GPIO41 is the SPISOMIB. // GPIO_setPinConfig(GPIO_41_SPIB_SOMI); GPIO_setPadConfig(41, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(41, GPIO_QUAL_ASYNC); // // GPIO22 is the SPICLKB. // GPIO_setPinConfig(GPIO_22_SPIB_CLK); GPIO_setPadConfig(22, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(22, GPIO_QUAL_ASYNC); // // GPIO5 is the SPISTEA. // GPIO_setPinConfig(GPIO_23_SPIB_STE); GPIO_setPadConfig(5, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(5, GPIO_QUAL_ASYNC); //SCIA -> mySCI0 Pinmux GPIO_setPinConfig(GPIO_28_SCIA_RX); GPIO_setPinConfig(GPIO_29_SCIA_TX); } int16_t int_to_char(int integer) { int temp,count=0,i,cnd=0; if (integer==0)//special case for 0 { ascii[0]='0'; return 1; } if(integer>>15) { /*CONVERTING 2's complement value to normal value*/ integer=~integer+1; for(temp=integer;temp!=0;temp/=10,count++); ascii[0]=0x2D; count++; cnd=1; } else for(temp=integer;temp!=0;temp/=10,count++); for(i=count-1,temp=integer;i>=cnd;i--) { ascii[i]=(temp%10)+0x30; temp/=10; } return count; }
//############################################################################# // // FILE: spi_ex4_loopback_dma.c // // TITLE: SPI Digital Loopback with DMA // //! \addtogroup driver_example_list //! <h1>SPI Digital Loopback with DMA</h1> //! //! This program uses the internal loopback test mode of the SPI module. Both //! DMA interrupts and the SPI FIFOs are used. When the SPI transmit FIFO has //! enough space (as indicated by its FIFO level interrupt signal), the DMA //! will transfer data from global variable sData into the FIFO. This will be //! transmitted to the receive FIFO via the internal loopback. //! //! When enough data has been placed in the receive FIFO (as indicated by its //! FIFO level interrupt signal), the DMA will transfer the data from the FIFO //! into global variable rData. //! //! When all data has been placed into rData, a check of the validity of the //! data will be performed in one of the DMA channels' ISRs. //! //! \b External \b Connections \n //! - None //! //! \b Watch \b Variables \n //! - \b sData - Data to send //! - \b rData - Received data //! // //############################################################################# // $TI Release: F28002x Support Library v3.04.00.00 $ // $Release Date: Fri Feb 12 18:58:34 IST 2021 $ // $Copyright: // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //########################################################################### // // Included Files // #include "driverlib.h" #include "device.h" // // Defines // #define FIFO_LVL 8 // FIFO interrupt level #define BURST FIFO_LVL // Each burst will empty the FIFO #define TRANSFER 4 // It will take 4 bursts of 8 to transfer // all data in rData // // Globals // uint16_t sData[32]; // Send data buffer uint16_t rData[32]; // Receive data buffer uint16_t ascii[10]={0}; const uint16_t DMA_char[6]={'\r','\n','D','M','A',':'}; // Place buffers in GSRAM #pragma DATA_SECTION(sData, "ramgs0"); #pragma DATA_SECTION(rData, "ramgs0"); volatile uint16_t done = 0; // Flag to set when all data transfered volatile uint16_t count=0; // // Function Prototypes void configGPIOs(void); void initDMA(void); void initSPIFIFO(void); void initSCI(void); int int_to_char(int); __interrupt void dmaCh5ISR(void); __interrupt void dmaCh6ISR(void); // // Main // void main(void) { uint16_t i; // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pullups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Interrupts that are used in this example are re-mapped to ISR functions // found within this file. // Interrupt_register(INT_DMA_CH5, &dmaCh5ISR); Interrupt_register(INT_DMA_CH6, &dmaCh6ISR); //Configuring pins configGPIOs(); // // Set up DMA for SPI use, initialize the SPI for FIFO mode // initDMA(); initSPIFIFO(); // Setup SCI for debugging purpose initSCI(); // // Initialize the data buffers // for(i = 0; i < 32; i++) { sData[i] = 256+i; rData[i]= 0; } // // Enable interrupts required for this example // Interrupt_enable(INT_DMA_CH5); Interrupt_enable(INT_DMA_CH6); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; GPIO_writePin(DEVICE_GPIO_PIN_LED1,0); GPIO_writePin(DEVICE_GPIO_PIN_LED2,0); // // Start the DMA channels // DMA_startChannel(DMA_CH6_BASE); DMA_startChannel(DMA_CH5_BASE); // // Wait until the DMA transfer is complete // while(1) { GPIO_togglePin(DEVICE_GPIO_PIN_LED1); DEVICE_DELAY_US(1000000); SCI_writeCharArray(SCIA_BASE,DMA_char,6); for(i=0;i<32;i++) { count=int_to_char(rData[i]); SCI_writeCharArray(SCIA_BASE,ascii,count); SCI_writeCharBlockingFIFO(SCIA_BASE, '\t'); } SCI_writeCharBlockingFIFO(SCIA_BASE, '\r'); SCI_writeCharBlockingFIFO(SCIA_BASE, '\n'); } } // // Function to configure SPI A in FIFO mode. // void initSPIFIFO() { // // Must put SPI into reset before configuring it // SPI_disableModule(SPIA_BASE); // // FIFO configuration // SPI_enableFIFO(SPIA_BASE); SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RXFF | SPI_INT_TXFF); SPI_setFIFOInterruptLevel(SPIA_BASE, (SPI_TxFIFOLevel)FIFO_LVL, (SPI_RxFIFOLevel)FIFO_LVL); // // SPI configuration. Use a 500kHz SPICLK and 16-bit word size. // SPI_setConfig(SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_SLAVE, 1000000, 16); SPI_disableLoopback(SPIA_BASE); SPI_enableModule(SPIA_BASE); } // // DMA setup for both TX and RX channels. // void initDMA() { // // Initialize DMA // DMA_initController(); // // Configure DMA Ch5 for TX. When there is enough space in the FIFO, data // will be transferred from the sData buffer to the SPI module's transmit // buffer register. // DMA_configAddresses(DMA_CH5_BASE, (uint16_t *)(SPIA_BASE + SPI_O_TXBUF), sData); DMA_configBurst(DMA_CH5_BASE, BURST, 1, 0); DMA_configTransfer(DMA_CH5_BASE, TRANSFER, 1, 0); DMA_configMode(DMA_CH5_BASE, DMA_TRIGGER_SPIATX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT); // // Configure DMA Ch5 interrupts // DMA_setInterruptMode(DMA_CH5_BASE, DMA_INT_AT_BEGINNING); DMA_enableInterrupt(DMA_CH5_BASE); DMA_enableTrigger(DMA_CH5_BASE); // // Configure DMA Ch6 for RX. When the FIFO contains at least 8 words to // read, data will be transferred from the SPI module's receive buffer // register to the rData buffer. // DMA_configAddresses(DMA_CH6_BASE, rData, (uint16_t *)(SPIA_BASE + SPI_O_RXBUF)); DMA_configBurst(DMA_CH6_BASE, BURST, 0, 1); DMA_configTransfer(DMA_CH6_BASE, TRANSFER, 0, 1); DMA_configMode(DMA_CH6_BASE, DMA_TRIGGER_SPIARX, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT); // // Configure DMA Ch6 interrupts // DMA_setInterruptMode(DMA_CH6_BASE, DMA_INT_AT_END); DMA_enableInterrupt(DMA_CH6_BASE); DMA_enableTrigger(DMA_CH6_BASE); } void initSCI(){ //mySCI0 initialization SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF | SCI_INT_TXFF | SCI_INT_FE | SCI_INT_OE | SCI_INT_PE | SCI_INT_RXERR | SCI_INT_RXRDY_BRKDT | SCI_INT_TXRDY); SCI_clearOverflowStatus(SCIA_BASE); SCI_resetTxFIFO(SCIA_BASE); SCI_resetRxFIFO(SCIA_BASE); SCI_resetChannels(SCIA_BASE); SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, (SCI_CONFIG_WLEN_8|SCI_CONFIG_STOP_ONE|SCI_CONFIG_PAR_NONE)); SCI_disableLoopback(SCIA_BASE); SCI_performSoftwareReset(SCIA_BASE); SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX0, SCI_FIFO_RX0); SCI_enableFIFO(SCIA_BASE); SCI_enableModule(SCIA_BASE); } // // DMA Channel 5 ISR // __interrupt void dmaCh5ISR(void) { DMA_stopChannel(DMA_CH5_BASE); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7); return; } // // DMA Channel 6 ISR // __interrupt void dmaCh6ISR(void) { uint16_t i; DMA_stopChannel(DMA_CH6_BASE); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7); // // Check for data integrity // //GPIO_writePin(DEVICE_GPIO_PIN_LED1,1); for(i = 0; i < 32; i++) { if (rData[i] != i) { // Something went wrong. rData doesn't contain expected data. GPIO_writePin(DEVICE_GPIO_PIN_LED2,1);//turn off green LED } } //Again triggering DMA transfer DMA_startChannel(DMA_CH6_BASE); DMA_startChannel(DMA_CH5_BASE); done = 1; return; } // // Configure GPIOs for external loopback. // void configGPIOs(void) { // // This test is designed for an external loopback between SPIA // and SPIB. // External Connections: // -GPIO40 and GPIO8 - SPISIMO // -GPIO41 and GPIO10 - SPISOMI // -GPIO22 and GPIO9 - SPICLK // -GPIO23 and GPIO11 - SPISTE // -GPIO31 is LED4 // -GPIO34 is LED5 GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1,GPIO_DIR_MODE_OUT);//setting LED1 pin as output GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED2,GPIO_DIR_MODE_OUT);//setting LED2 pin as output // // GPIO10 is the SPISOMIA. // GPIO_setPinConfig(GPIO_10_SPIA_SOMI); GPIO_setPadConfig(10, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(10, GPIO_QUAL_ASYNC); // // GPIO11 is the SPISIMO. // GPIO_setPinConfig(GPIO_11_SPIA_SIMO); GPIO_setPadConfig(11, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(11, GPIO_QUAL_ASYNC); // // GPIO09 is the SPICLKA. // GPIO_setPinConfig(GPIO_9_SPIA_CLK); GPIO_setPadConfig(9, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(9, GPIO_QUAL_ASYNC); // // GPIO5 is the SPISTEA. // GPIO_setPinConfig(GPIO_5_SPIA_STE); GPIO_setPadConfig(5, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(5, GPIO_QUAL_ASYNC); //SCIA -> mySCI0 Pinmux GPIO_setPinConfig(GPIO_28_SCIA_RX); GPIO_setPinConfig(GPIO_29_SCIA_TX); } int16_t int_to_char(int integer) { int temp,count=0,i,cnd=0; if (integer==0)//special case for 0 { ascii[0]='0'; return 1; } if(integer>>15) { /*CONVERTING 2's complement value to normal value*/ integer=~integer+1; for(temp=integer;temp!=0;temp/=10,count++); ascii[0]=0x2D; count++; cnd=1; } else for(temp=integer;temp!=0;temp/=10,count++); for(i=count-1,temp=integer;i>=cnd;i--) { ascii[i]=(temp%10)+0x30; temp/=10; } return count; }
Just to add a small correction to the Arduino code. The SPI clock divider was set to 84 so that its clock operates at 1 MHz same as configured for the TMS320F280025C. I was later testing with slower clock rates to check if there is any improvement. I did not find any improvement with reduced clock rates.
Have you already tried probing the SPI bus with logic analyzer to check the bus activity? Can you share the SPI logic analyzer snapshots.Have you tried making just one transfer and see whether you see the same problem.
I'm in middle of a important project. I can take deeper look into this only next week
Dear Manoj,
I tried probing through logic analyzer and verified the data integrity. I will make a setup again to capture for you. I hardly doubt at the transmission side as SPIA on the same controller is able to receive all data correctly. However I will try single transfer as proposed by you. I would request you to take an early look into provided codes once you get free from your ongoing project. We have already sent PCBs for production and I am afraid if we might need to hold and do a revision by replacing SPIB with SPIA.
Asad,
I briefly looked into your code and couldn't figure out anything which caused concern. I need to try running your code and check whether I see the same behavior.
Regards,
Manoj
Dear Manoj
I did a detailed testing over the weekend with logic analyzer. I used another TMS320F280025C launchpad as a master in place of Arduino. I had one finding that I want to share. I have been connecting both the master as slave to the USB ports of the laptop. I have noticed that when my laptop is connected with power charger then SPI slave as well as the logic analyzer receives lot of error transmissions. However when I disconnect the power charger the logic analyzer sniffs all the data correctly. Next I tested SPIA and SPIB on slave side controller. The test was done with external power charger disconnected. SPIA receives all data correctly. SPIB has some spurious readings. Please find below some readings from SPIB:
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 4102 15 8 9 10 11 12 13 14 79 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16399 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SPIB:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
The frequency of error value is reduced a lot with external power charger disconnected. I am looking into it from noise perspective. Please test at your end on TMS320F280025C Launchpad to see if you find any difference between SPIA and SPIB reception.
Asad,
Based on your description, it looks like SPI signals are getting affected by EMI noise in your setup (power charger). Did you observe the incorrect data on both SPIA / SPIB when using power charger? Also, when both the master and slave boards are connected? Are you making sure to connect GND pins of both master and slave setup?
Since we are dealing with EMI noise, it would be better to use oscilloscope instead of logic analyzer. Please share your analyzer snapshots, oscilloscope snapshots and photograph of your setup. I shall get started looking into your code.
Regards,
Manoj
Dear Manoj,
We are off from work and will resume on Friday. I will try to capture oscilloscope results and test setup with you then. It is our observation that SPIA is much less prone to noise. It is getting data correctly more than 95% in all cases. However SPIB appears to be more sensitive and is getting high percentage error in noise case. We have replaced SPIB with SPIA in our design to reduce chances of bad communication in production. Thanks alot for continued support.
Asad,
We want to understand this problem and see whether we have a genuine issue. This could be board issue, setup issue (or) remotely device issue. Please do share your oscilloscope snapshots and test setup photos to help us get to the bottom of this problem.
As of now, there are no known issues with SPIA / SPIB.
Regards,
Manoj
Dear Manoj,
Sorry for the late reply. I got infected with CoVid and there was 3 week absence from office. We don't have any conclusive finding yet. It could be due to our jumper wires or the external noise. It will take me some time to get back to the SPI task. We can close this ticket. If there is any new findings then I will share with you.
Sorry to hear that. Wishing you a speed recovery.
I shall close this ticket for now.