Search code examples
cmsp430code-composerstm32f4

CC3200 SPI Slave bad receive


Solved: I had to handle CS/NSS pin for slave. Add some delay before and after TX.

void SlaveMain()
{
    MAP_SPIReset(GSPI_BASE);

    MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
                     SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
                     (SPI_SW_CTRL_CS |
                     SPI_4PIN_MODE |
                     SPI_TURBO_OFF |
                     SPI_CS_ACTIVELOW |
                     SPI_WL_8));

    MAP_SPIEnable(GSPI_BASE);
}

while(1)
{
    MAP_SPICSEnable(GSPI_BASE);
    MAP_SPIDataGet(GSPI_BASE, &data);
    Report("Got: %d\n\r", data);
    MAP_SPICSDisable(GSPI_BASE);
}

My problem is that I receive wrong data from STM32F4 board via SPI. My CC3200 board SPI slave config:

#define SPI_IF_BIT_RATE  100000
void SlaveMain()
{
    // 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_SW_CTRL_CS |
                 SPI_4PIN_MODE |
                 SPI_TURBO_OFF |
                 SPI_CS_ACTIVEHIGH |
                 SPI_WL_8));

   // 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);

   Message("Enabled SPI Interface in Slave Mode\n\rReceived : ");
}

Interrupt:

static void SlaveIntHandler()
{
    unsigned long ulRecvData;
    unsigned long ulStatus;

    ulStatus = MAP_SPIIntStatus(GSPI_BASE,true);

    MAP_SPIIntClear(SSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);

    if(ulStatus & SPI_INT_RX_FULL)
    {
    MAP_SPIDataGetNonBlocking(GSPI_BASE,&ulRecvData);
    Report("Received: %d\n\r",ulRecvData);
    }
}

And my STM32F4 board config for SPI Master:

void MX_SPI2_Init(void)
{
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 10;
  HAL_SPI_Init(&hspi2);
}

  uint8_t data;

  while (1)
  {
    HAL_Delay(500);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
    data = 6;
    HAL_SPI_Transmit(&hspi2, &data, 1, 50);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
    HAL_Delay(500);
  }

Result I get from CC3200 and it changes after I reset Master device: Wrong received data. Must show 6.

Where could be a problem?


Solution

  • (Slave is configured to SW controlled CS/NSS pin, and you currently do not handle that). SPI usually uses CS pin to resync, so if one bit is lost in your transmission, or the slave starts up after master has started to transmit), it will currently never recover (SPI has no START/STOP bits).