Page 1 of 1

How to ensure the SPI command always goes through in RTOS

Posted: Thu Nov 04, 2021 6:06 am
by zazas321
Hello. I have been learning RTOS and ESP32 for a while now. I have written my own flash memory drivers but I have got some concerns.

This is my write to flash memory function:

Code: Select all

bool FLASH_write_page(spi_device_handle_t spi, int16_t pages, uint8_t* buf,uint8_t size)

{
    esp_err_t ret;
    spi_transaction_t SPITransaction;

    if(FLASH_check_if_write_enabled(external_flash)==false){ // returns true if write is already enabled
        FLASH_write_enable(external_flash);
    }
    if(FLASH_check_if_busy(spi) == true){ // return true if flash is not busy
        memset(&SPITransaction, 0, sizeof(SPITransaction));       //Zero out the transaction
        uint8_t command_byte = 0x02;
        uint32_t addr = pages * 256; // page size is 256 bytes
	    SPITransaction.cmd=command_byte;
        SPITransaction.addr=addr;
        SPITransaction.tx_buffer = buf;
        SPITransaction.length = 8*size;
        ret = spi_device_polling_transmit(spi, &SPITransaction);
        assert(ret==ESP_OK);
        return 1;
    }
    return 0;
}
My concern is, that sometimes when I call these commands back to back, the flash chip is busy (the flag in status register is not clear and the flash chip is not ready to receive another command).
For example:

Code: Select all

FLASH_write_page(spi,1,data,sizeof(data)); will work because it is the first command
FLASH_write_page(spi,2,data,sizeof(data));// is likely to fail because the flash chip is busy from the first command
FLASH_write_page(spi,3,data,sizeof(data)); // this is likely to sucess because the MCU had enough time to clear the flag.

What is the best way to ensure that all called commands are executed? Is it appropriate to create RTOS task to handle all the flash memory functions? How can I use this task to perform all operations - write/erase/read?

Re: How to ensure the SPI command always goes through in RTOS

Posted: Fri Nov 05, 2021 1:48 pm
by nilesh_m
Hi, I am not sure about the best approach. However in case you wanted to use task which will handle all operation then it is a good way.
Task will have state machine in which it will monitor whether flash is busy or not. And once it is available whatever query it is having it can execute.
You can also use semaphore to trigger read/write/erase operation as per your need.
Like, when flash is busy keep task in waiting state and once flash operation is completed you can release semaphore which will resume task execution.

Please note, you need to handle operation as per the status of the flash.

Just a thought. :)