Diego Rodrigo
Diego Rodrigo

Reputation: 1

SPI Slave using Interrupts on STM32

I'm trying to connect my STM32F427 microcontroller to my PC using the SPI protocol. To facilitate this communication, I'm using the MCP2210 developed by Microchip, which acts as the master in this setup.

I have implemented a slave code using the HAL library, aiming to receive data from a master device. I'm using interrupts to handle latency issues, but unfortunately, it's not functioning as expected. I am unable to receive any data from the master device or send a response back to it. However, the SPI interrupts seem to be working correctly, as the program enters the HAL_SPI_RxCpltCallback function when I send SPI data.

#define SPI_TIMEOUT 1000
uint8_t spi_tx_data[9];
uint8_t spi_rx_data[9];

uint8_t rx_cmplt = 0;

int main(void)
{
      MX_GPIO_Init();
      MX_SPI1_Init();
      HAL_Init();
      SystemClock_Config();

  spi_tx_data[0] = 0x34;
  spi_tx_data[1] = 0x34;
  spi_tx_data[2] = 0x34;
  spi_tx_data[3] = 0x34;
  spi_tx_data[4] = 0x09;
  spi_tx_data[5] = 0x05;
  spi_tx_data[6] = 0x05;
  spi_tx_data[7] = 0x00;
  spi_tx_data[8] = 0x02;


  while (1)
      {

      HAL_SPI_Receive_IT(&hspi1, spi_rx_data, 9);

       }


}

void HAL_SPI_RxCpltCallback (SPI_HandleTypeDef *hspi1) {

// This function is called when the SPI recepcion finished

HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15); //Toggle the led to see if we detect any  SPI signal. 

HAL_SPI_Transmit(&hspi1, spi_tx_data, sizeof(spi_tx_data), SPI_TIMEOUT); //

if (spi_rx_data[0]==33){
        HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_10); //Toggle led if we recibe this data

    }

}

My SPI inicialitation according with the master: Mode 0 and NSS Soft.

static void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  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 = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

I prove this code with the SPI Terminal provided by Microchip for proving how MCP2210 works but I´ve also codified a programm with hidapi library to send data to the MCP2210 following the instruction of the datasheet: After execute this code, I´ve programmed the MCP2210 o work with the correct baudrate (1MHz), with the correct GP as CS, in mode 0 and for a SPI data size of 9 bytes.

Data sheet information: Byte Index Meaning 0: 0x00 Necessary to add a byte for correct functioning (no included in datasheet) 1: 0x42 Transfer SPI Data – command code 2: XxXX The number of bytes to be transferred in this packet (from 0 to 60 inclusively) 3: 0x00 Reserved 4 0x00 Reserved 5-63 The SPI Data to be sent on the data transfer

And the expected response: Byte Index Meaning 0 0x42 – Transfer SPI Data – echoes back the given command code 1 0x00 – SPI Data accepted – Command Completed Successfully – SPI data accepted 2 How many SPI received data bytes the chip is sending back to the host 3 0x10 – SPI Transfer Engine Status: SPI transfer finished – no more data to send 4-63 SPI received data bytes. The number of data bytes is specified at byte index 2

Code for sending data to the master with hidapi:

int main()
{

    //Buffers for transmission and recepcion
    unsigned char data[65];
    unsigned char rdata[65];


    // Open device
    hid_device* dev = hid_open(0x04D8, 0x00DE, NULL);

    if (!dev) {
        std::cerr << "Error: no se pudo abrir el dispositivo HID" << std::endl;
        return 1;
    }



    data[0] = 0x00; //Comand to iniciate SPI transmision 
    data[1] = 0x42;                   // 0x42no. of SPI bytes to transfer
    data[2] = 0x01;  // ox3c = 60
    data[3] = 0x00;
    data[4] = 0x00;
    data[5] = 0x33; // MSB sent first  Data send 
    for (int r = 6; r < 64; r++) {
        data[r] = 0xAA;
    }
    //const unsigned char data =  1;
    // Enviar datos al dispositivo HID
    int x;
    while (1) {
        cout << "Press 1 to send and recibe data, press 2 to finish the programm: ";
        cin >> x; // Get user input from the keyboard
        if (x == 1) {
            
                
                res = hid_write(dev, data, 9);
                std::this_thread::sleep_for(std::chrono::milliseconds(4));
                res = hid_read(dev, rdata, 9);  // read 0x42 response data sent
            
            while (rdata[2] == 0x00) { //Treak to see if there are more data available

                data[2] = 0x01;
                res = hid_write(dev, data, 6); //Send data 
                std::this_thread::sleep_for(std::chrono::milliseconds(4));
                res = hid_read(dev, rdata, 6);  // read 0x42 response data sent
            }

            int num_valores = sizeof(data) / sizeof(data[0]);
            std::cout << "Los valores enviados son: ";

            //Printing sended buffer:
            for (int i = 0; i < 64; i++) {
                std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)data[i] << " ";
            }

     


            std::cout << "Response: \n";


            //Printing recibed buffer:
            for (int i = 0; i < 64; i++) {
                std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)rdata[i] << " ";
            }
            std::cout << std::endl;

        }

        if (x == 2) {
            printf("FIN \n");
            hid_close(dev);
            return 0;
            std::cout << std::endl;
        }
    }



    if (res < 0) {
        std::cerr << "Error al enviar datos al dispositivo HID" << std::endl;
    }



    //close
    printf("FIN \n");
    hid_close(dev);
    return 0;

When I execute this code with the MCP2210 connected to the PC and the STM32 (configured as a Slave SPI), I don't receive the 0x33 code in the slave (the LED doesn't blink). However, I am receiving SPI data because the code is entering the HAL_SPI_RxCpltCallback function. Additionally, in the master program, I'm not receiving any valid data when I print the received buffer. Does anyone have an idea of what could be happening?

Thanks in advance!

Upvotes: 0

Views: 690

Answers (0)

Related Questions