I have connected two CC3200s and I am using MAP_SPITransfer on the master side and on the slave side I have taken code from the spi demo. I am transferring 4 bytes back and forth (only need three but thought four would work better). Since the master reads at the same time it writes I know that my slave response must be delay by one transfer. However, it seems the response seen by the master is also a byte behind as well as the expected one message behind. From the slave side what seems to be happening is that Tx buffer empty flag is not set until I get a transfer from the main. So tht the slave ISR can never send what it in the first byte of the tx buffer on the first attempt.
I know this may not seem clear so I have attached the code that I have on the two CC3200s. Each side has a character capture capability. On the master side I have a few pattern choices to send and the slave receives them fine so whatever pattern is sent is immaterial to the problem. On the slave side I can load the tx buffer with a couple of patterns that I want to send back to the master. If I choose a slave tx pattern of 0,0,0,0 for the first exchange, and 0x31, 0x32, 0x33, 0x34, on the 2nd exchange, the master sees 0x00, 0x31, 0x32, 0x33, on the second exchange. This is why I say there is a byte lag. Maybe this is the way it must be unless there is a way to get the tx buffer empty flag to set, because I tried a non-blocking pre-write and it was ignored.
My time line is becoming critical so I hope someone will help a ex-TIer. Your CC3200 is a few quantum leaps beyond the TI-960 I used to program. Besides the forum, I can be reached at:
john.hite@halosmartlabs.com
Thanks,
John Hite
HARM 78-93, seems I will never forget badge #152301.
or
jvh24521@gmail.com
Thanks,
jh
// Standard includes #include <string.h> // Driverlib includes #include "hw_types.h" #include "hw_memmap.h" #include "hw_common_reg.h" #include "hw_ints.h" #include "spi.h" #include "rom.h" #include "rom_map.h" #include "utils.h" #include "prcm.h" #include "uart.h" #include "interrupt.h" // Common interface includes #include "uart_if.h" #include "pinmux.h" #define APPLICATION_VERSION "1.1.1" #define SPI_IF_BIT_RATE 100000 #define TR_BUFF_SIZE 100 //***************************************************************************** // GLOBAL VARIABLES -- Start //***************************************************************************** static unsigned char g_ucTxBuff[TR_BUFF_SIZE]; static unsigned char g_ucRxBuff[TR_BUFF_SIZE]; static unsigned char ucTxBuffNdx; static unsigned char ucRxBuffNdx; #if defined(ccs) extern void (* const g_pfnVectors[])(void); #endif #if defined(ewarm) extern uVectorEntry __vector_table; #endif //***************************************************************************** // GLOBAL VARIABLES -- End //***************************************************************************** //***************************************************************************** // //! SPI Master mode main loop //! //! This function configures SPI modelue as master and enables the channel for //! communication //! //! \return None. // //***************************************************************************** void MasterMain() { int i,j; unsigned long ulUserData; unsigned long ulDummy; unsigned char f[] = {0x11,0x11, 0xEE}; unsigned char s[] = {0x16, 0x16, 0xE9}; // Set Tx buffer index ucTxBuffNdx = 0; ucRxBuffNdx = 0; // // Reset SPI // MAP_SPIReset(GSPI_BASE); // // Configure SPI interface // MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI), SPI_IF_BIT_RATE,SPI_MODE_MASTER,SPI_SUB_MODE_0, (SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF | SPI_CS_ACTIVEHIGH | SPI_WL_32)); // // Enable SPI for communication // MAP_SPIEnable(GSPI_BASE); Message("Enabled SPI Interface in Master Mode\n\r"); Report("\n\rType here (Press enter to exit) :"); ulUserData = 0; while(ulUserData != '\r') { // Read a character from UART terminal ulUserData = MAP_UARTCharGet(UARTA0_BASE); // Echo it back MAP_UARTCharPut(UARTA0_BASE,ulUserData); // Push the character over SPI switch ((unsigned char) ulUserData) { case 's': g_ucTxBuff[0] = 0x01; g_ucTxBuff[1] = 0x01; g_ucTxBuff[2] = ~0x01; break; case 'e': g_ucTxBuff[0] = 0x04; g_ucTxBuff[1] = 0x04; g_ucTxBuff[2] = ~0x04; break; case 'a': g_ucTxBuff[0] = 0x06; g_ucTxBuff[1] = 0x06; g_ucTxBuff[2] = ~0x06; break; default: g_ucTxBuff[0] = 0x35; g_ucTxBuff[1] = 0x36; g_ucTxBuff[2] = 0x37; g_ucTxBuff[3] = 0x38; break; } Report("\r\n\nMaster sending: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", g_ucTxBuff[0], g_ucTxBuff[1], g_ucTxBuff[2], g_ucTxBuff[3]); MAP_SPITransfer(GSPI_BASE,g_ucTxBuff, g_ucRxBuff,4, SPI_CS_ENABLE|SPI_CS_DISABLE); Report("\r\nMaster received: "); for (j = 0; j < 8; j++) { //Report("c:%c, 0x:%02X", g_ucRxBuff[j], g_ucRxBuff[j]); Report("0x%02X, ", g_ucRxBuff[j]); } } // // Disable chip select // //MAP_SPICSDisable(GSPI_BASE); } //***************************************************************************** // //! Board Initialization & Configuration //! //! \param None //! //! \return None // //***************************************************************************** static void BoardInit(void) { /* In case of TI-RTOS vector table is initialize by OS itself */ #ifndef USE_TIRTOS // // Set vector table base // #if defined(ccs) MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]); #endif #if defined(ewarm) MAP_IntVTableBaseSet((unsigned long)&__vector_table); #endif #endif // // Enable Processor // MAP_IntMasterEnable(); MAP_IntEnable(FAULT_SYSTICK); PRCMCC3200MCUInit(); } //***************************************************************************** // //! Main function for spi demo application //! //! \param none //! //! \return None. // //***************************************************************************** void main() { // // Initialize Board configurations // BoardInit(); // // Muxing UART and SPI lines. // PinMuxConfig(); // // Enable the SPI module clock // MAP_PRCMPeripheralClkEnable(PRCM_GSPI,PRCM_RUN_MODE_CLK); // // Initialising the Terminal. // InitTerm(); // // Clearing the Terminal. // ClearTerm(); // // Display the Banner // Message("\n\n\n\r"); Message("\t\t ********************************************\n\r"); Message("\t\t CC3200 SPI Demo Application \n\r"); Message("\t\t Master mode \n\r"); Message("\t\t ********************************************\n\r"); Message("\n\n\n\r"); // // Reset the peripheral // MAP_PRCMPeripheralReset(PRCM_GSPI); MasterMain(); while(1) { } }
// Standard includes #include <string.h> // Driverlib includes #include "hw_types.h" #include "hw_memmap.h" #include "hw_common_reg.h" #include "hw_ints.h" #include "spi.h" #include "rom.h" #include "rom_map.h" #include "utils.h" #include "prcm.h" #include "uart.h" #include "interrupt.h" // Common interface includes #include "uart_if.h" #include "pinmux.h" #define APPLICATION_VERSION "1.1.1" #define SPI_IF_BIT_RATE 100000 #define TR_BUFF_SIZE 100 #define MASTER_MSG "This is CC3200 SPI Master Application\n\r" #define SLAVE_MSG "This is CC3200 SPI Slave Appl\0ication\n\r" //***************************************************************************** // GLOBAL VARIABLES -- Start //***************************************************************************** static unsigned char g_ucTxBuff[TR_BUFF_SIZE]; static unsigned char g_ucRxBuff[TR_BUFF_SIZE]; static unsigned char ucTxBuffNdx; static unsigned char ucRxBuffNdx; unsigned long ulUserData = 0; #if defined(ccs) extern void (* const g_pfnVectors[])(void); #endif #if defined(ewarm) extern uVectorEntry __vector_table; #endif //***************************************************************************** // GLOBAL VARIABLES -- End //***************************************************************************** //***************************************************************************** // //! Board Initialization & Configuration //! //! \param None //! //! \return None // //***************************************************************************** static void BoardInit(void) { /* In case of TI-RTOS vector table is initialize by OS itself */ #ifndef USE_TIRTOS // // Set vector table base // #if defined(ccs) MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]); #endif #if defined(ewarm) MAP_IntVTableBaseSet((unsigned long)&__vector_table); #endif #endif // // Enable Processor // MAP_IntMasterEnable(); MAP_IntEnable(FAULT_SYSTICK); PRCMCC3200MCUInit(); } //***************************************************************************** // //! SPI Slave Interrupt handler //! //! This function is invoked when SPI slave has its receive register full or //! transmit register empty. //! //! \return None. // //***************************************************************************** static void SlaveIntHandler() { unsigned long ulRecvData; unsigned long ulStatus; ulStatus = MAP_SPIIntStatus(GSPI_BASE,true); MAP_SPIIntClear(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY); //Send if(ulStatus & SPI_INT_TX_EMPTY) { MAP_SPIDataPut(GSPI_BASE,g_ucTxBuff[ucTxBuffNdx]); ucTxBuffNdx++; } //Receive if(ulStatus & SPI_INT_RX_FULL) { MAP_SPIDataGetNonBlocking(GSPI_BASE,&ulRecvData); g_ucRxBuff[ucRxBuffNdx%3] = ulRecvData; //Report("0x%2X",ulRecvData); ucRxBuffNdx++; } } void SlaveSetup() { // Set Tx buffer index // ucTxBuffNdx = 0; ucRxBuffNdx = 0; // Reset SPI MAP_SPIReset(GSPI_BASE); // Configure SPI interface MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI), SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0, (SPI_HW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF | SPI_CS_ACTIVEHIGH | SPI_WL_32)); // Register Interrupt Handler MAP_SPIIntRegister(GSPI_BASE,SlaveIntHandler); // Enable Interrupts MAP_SPIIntEnable(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY); // Enable SPI for communication MAP_SPIEnable(GSPI_BASE); // Print mode on uart Message("Enabled SPI Interface in Slave Mode \n\rReceived : "); } SlaveMain(void) { int i; Report("\n\rType here (Press enter to exit) :"); ulUserData = 0; while(ulUserData != '\r') { // Read a character from UART terminal ulUserData = MAP_UARTCharGet(UARTA0_BASE); // Echo it back MAP_UARTCharPut(UARTA0_BASE,ulUserData); switch (ulUserData) { case 'c': case 'C': g_ucTxBuff[0] = 0x43; g_ucTxBuff[1] = 0x43; g_ucTxBuff[2] = ~0x43; break; case 'a': g_ucTxBuff[0] = 0x06; g_ucTxBuff[1] = 0x06; g_ucTxBuff[2] = ~0x06; break; case 'n': g_ucTxBuff[0] = 0x15; g_ucTxBuff[1] = 0x15; g_ucTxBuff[2] = ~0x15; break; case '1': g_ucTxBuff[0] = 0x31; g_ucTxBuff[1] = 0x32; g_ucTxBuff[2] = 0x33; g_ucTxBuff[3] = 0x34; break; default: g_ucTxBuff[0] = (unsigned char)ulUserData; g_ucTxBuff[1] = g_ucTxBuff[0]; g_ucTxBuff[2] = ~g_ucTxBuff[0]; break; } Report("\r\nSetting slave return values: "); for (i = 0; i < 3; i++) { Report("0x%02X, ", g_ucTxBuff[i]); } ucTxBuffNdx = 0; ucRxBuffNdx = 0; } } //***************************************************************************** // //! Main function for spi demo application //! //! \param none //! //! \return None. // //***************************************************************************** void main() { // // Initialize Board configurations // BoardInit(); PinMuxConfig(); MAP_PRCMPeripheralClkEnable(PRCM_GSPI,PRCM_RUN_MODE_CLK); InitTerm(); ClearTerm(); Message("\n\n\n\r"); Message("\t\t ********************************************\n\r"); Message("\t\t CC3200 SPI Demo Application \n\r"); Message("\t\t Slave mode \n\r"); Message("\t\t ********************************************\n\r"); Message("\n\n\n\r"); MAP_PRCMPeripheralReset(PRCM_GSPI); SlaveSetup(); SlaveMain(); while(1); }