cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Receive more characters than sent

Patsch36
Associate II

I try to setup a SPI COmmunication to do some "cross-communication" for Safety Reasons.

So in my test setup, i read characters from UART, send them via SPI to the Slave, the Slave logs them via UART and ackknowledges them through sending an "39".

Sending from Master to Slave and logging them works just fine. For example typing "21" in the serial monitor of the master makes the slave logging 21 on another serial monitor.

But when the slave should send the "39" Back, the weird magic happens. In the first iteration, I receive 39 on the masters side. So everything's good.

But typing "21" Again, the slave logs 21 again, bu on the master's Side, I don't receive 39 but 393333333333333333333333333333333333333333333333333333333333333333 and in the third iterations it's even 333333333333333333333333333333333393333333333333333333333333333333333333333333333333333333333333333. Changing the number to another makes me recognizing, that the numbers that are too many are always the first number of the originals. I'm really wondering, because while debugging i saw that it call's the SPI_Transmit-Function only ones with a message of "39" and a length of 2.

The master does nothing other than receiving SPI input and logging it directly via UART. I really Wonder where the other numbers come from.

 

HERE's my Configuration:

// Master

static void MX_SPI1_Init(void)

{
  /* SPI1 parameter configuration*/

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
//    Error_Handler();
  }
}

// Slave
	  hspi1.Instance = SPI1;
	  hspi1.Init.Mode = SPI_MODE_SLAVE;
	  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
	  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
	  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
	  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
	  hspi1.Init.NSS = SPI_NSS_SOFT;
	  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
	  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
	  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
	  hspi1.Init.CRCPolynomial = 7;
	  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
	  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

// Master Application:
while (1)
    {

		uint8_t RX_Buffer[BUFFER_SIZE] = {0};
		uint8_t TX_Buffer[BUFFER_SIZE] = {0};
        // Receive UART command
        HAL_UART_Receive(&huart2, TX_Buffer, BUFFER_SIZE, 2000);

        if (TX_Buffer[0] != '\0')
        {

            // Transmit received command over SPI
            MEF_SPIMessage mes = MEF_SPIMessage();
            mes.DevieID = 1;
            mes.TX_Data = TX_Buffer;
            mes.TX_DataLength = BUFFER_SIZE;
            spi->Send(mes);

            // Receive SPI response
            mes.DevieID = 1;
            mes.RX_Data = RX_Buffer;
            mes.RX_DataLength = BUFFER_SIZE;
            spi->Receive(mes);
            while ((hspi1.Instance->SR & SPI_SR_RXNE) != 0) {
                uint16_t dummy_data = hspi1.Instance->DR; // Read data to clear the buffer
                HAL_UART_Transmit(&huart2, (uint8_t*)dummy_data, sizeof(dummy_data)*2, HAL_MAX_DELAY);
            }
            // Transmit SPI response over UART
            HAL_UART_Transmit(&huart2, mes.RX_Data, mes.RX_DataLength, HAL_MAX_DELAY);
        }
}

// Slave Application
	while (1)
	{

		MEF_SPIMessage recmes = MEF_SPIMessage();
		// 1. Wait for Sync Byte (42)
		uint8_t RX_Buffer[8] = {0};
		for(int index = 0; index < 8; index++)
		{
			RX_Buffer[index] = '\0';
		}
		recmes.DevieID = 0;
		recmes.RX_Data = (uint8_t*) RX_Buffer;
		recmes.RX_DataLength = 8;
		spi->Receive(recmes);

		if(recmes.RX_Data[0] == '\0')
		{
			continue;
		}

		strcpy(val_string, "RECEIVED: ");
		strcat(val_string, (char*)recmes.RX_Data);

		uart->send((uint8_t*)val_string, sizeof(val_string));
		HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);

		// 2. Send Ack
		MEF_SPIMessage sendmes = MEF_SPIMessage();
		sendmes.DevieID = 0;
		sendmes.TX_Data = (uint8_t*)"39";
		sendmes.TX_DataLength = 2;
		spi->Send(sendmes);
		while ((hspi1.Instance->SR & SPI_SR_TXE) == 0) {
		    // Wait for the transmit buffer to become empty
		}
}



1 REPLY 1
jiangfan
ST Employee

to simplify the problem, it is suggested to first just check if slave has sent extra data - by probing with a scope.