SPI Master Slave handshake with spi_device_queue_trans

Aussie Susan
Posts: 45
Joined: Thu Aug 22, 2019 3:48 am

Re: SPI Master Slave handshake with spi_device_queue_trans

Postby Aussie Susan » Tue Feb 04, 2020 1:58 am

I might be wrong here but I suspect you are thinking the SPI module operates in the same was as the UART.
In a UART you can have separate send and receive operations - they can even overlap (i.e. send while receiving).
With the SPI module, you *exchange* values - the master controls when the exchange occurs but each SPI module sends and receives at the same time.
Therefore the slave MUST set up the value(s) to be sent and then wait for the master to initiate each value exchange. The slave will be told when an exchange has completed (typically so it can read the received value and perhaps get the next value to send loaded into the module).
Therefore is really does not make sense to split the Tx and Rx sides of an SPI exchange.
This may be why you are having so much difficulty in getting it to work.
Susan

rosenrot
Posts: 25
Joined: Wed Jan 01, 2020 9:28 pm

Re: SPI Master Slave handshake with spi_device_queue_trans

Postby rosenrot » Tue Feb 04, 2020 8:17 am

Hi Susan,

you are partly right. I'm coming from using UART. However, the principle of SPI is rather understandable to me. This is another scenario I tried. It is running in a single task. SPI queue size is set to RX_N = 3. What I see is that I'm not receiving all data that are send by the master. I don't understand why. I thought that the post_trans_cb is called once the transmission is completed.

I'm quite sure that I get something wrong about how to use these functions.

Code: Select all

static void spi_slave_tx_task(){
    data_t data;

    empty_buffer_queue = xQueueCreate(RX_N, sizeof(spi_slave_transaction_t *));
    static spi_slave_transaction_t trans_desc[RX_N];

    for(int i = 0; i < RX_N; i++){
        trans_desc[i].tx_buffer = send_buffer[i];
        trans_desc[i].rx_buffer = receive_buffer[i];
        trans_desc[i].length = SPI_BUF_SIZE_SMALL*8;
        ((char*)trans_desc[i].rx_buffer)[0] = 0;

        spi_slave_transaction_t * ptr = &trans_desc[i];
        xQueueSendToBack(empty_buffer_queue, &ptr, portMAX_DELAY);
    }
    spi_slave_transaction_t * trans = NULL;
    int i = 0;
    TickType_t xLastWakeTime = xTaskGetTickCount();

    while(1){
        trans=&trans_desc[i%RX_N];
            if(xQueueReceive(queue_spi_output, &data, 0)){
                memcpy(trans->tx_buffer,&data, sizeof(data_t));
            }else{
                memset(trans->tx_buffer,0,SPI_BUF_SIZE_SMALL);
            }

            spi_slave_queue_trans(RCV_HOST, trans, 0);
            spi_slave_get_trans_result(RCV_HOST, &trans, 0);
            i++;
            if(i==RX_N){
                i=0;
                vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(2));
            }
            
    }
}
post_trans_cb handler to get received data:

Code: Select all

//Called after transaction is sent/received. We use this to set the handshake line low.
void my_post_trans_cb(spi_slave_transaction_t *trans) {
    data_t data;
    memcpy(&data,trans->rx_buffer,sizeof(data_t));
    xQueueSendFromISR(queue_spi_input, &data, portMAX_DELAY);

    WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1<<spi_gpio_hs));
}

ESP_Sprite
Posts: 9607
Joined: Thu Nov 26, 2015 4:08 am

Re: SPI Master Slave handshake with spi_device_queue_trans

Postby ESP_Sprite » Tue Feb 04, 2020 9:57 am

Not sure about when it's called, but when post_trans_cb is called, the transaction still is 'owned' by the SPI driver; you only get it back when get_trans_result returns it.

rosenrot
Posts: 25
Joined: Wed Jan 01, 2020 9:28 pm

Re: SPI Master Slave handshake with spi_device_queue_trans

Postby rosenrot » Tue Feb 04, 2020 10:43 am

Ah, I thought once post_trans_cb is called the received data would be available.

So how would I use this two functions individually from each other? If I want to fill the queue without waiting for the answer, I need two different tasks? Or am I thinking wrong?

Who is online

Users browsing this forum: No registered users and 80 guests