cancel
Showing results for 
Search instead for 
Did you mean: 

How to play Audio files from External Flash memory using STM32 Part2

A.ALUR_SWAMY
Associate

How to create a driver to handle External flash memory using SPI?

Welcome back!
In this  part we'll cover creating driver functions for STM32 microcontroller to interact with external memory device through the SPI peripheral

We will now proceed to create the following SPI flash driver functions to enable access to the external SPI flash memory.
readDeviceId () :
 
This function attempts to read the external memory device ID by transmitting the SPI command CMD_RDID (0x90) and  then receiving the respective device ID as mentioned in the Flash memory datasheet W25Q64JV Datasheet (winbond.com)
#define flashSPIh hspi2
#define CMD_RDID  0x90    
static uint16_t readDeviceId ()
{
    FLASH_CS_LOW();
    uint8_t bufferOut[] = {CMD_RDID, 0, 0, 0};
    uint8_t bufferIn[] = {0, 0};    
    if (HAL_SPI_Transmit(&flashSPIh, bufferOut, sizeof(bufferOut), 1000) !=HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       }
    if (HAL_SPI_Receive(&flashSPIh, bufferIn, sizeof(bufferIn), 1000) != HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       }
    FLASH_CS_HIGH();
    //combine bytes
    return bufferIn[0]<<8 | bufferIn[1];
}
readStatusRegister () :
 
This function reads the 8-bit long Status Register of the SPI flash memory by issuing the command CMD_RDSR (0x05).This allows the BUSY status bit of the external flash memory to be checked to determine when the cycle is complete and if the device can accept another instruction.
#define CMD_RDSR 0x05
static uint8_t readStatusRegister()
{
    FLASH_CS_LOW();
   
    uint8_t bufferOut[] = {CMD_RDSR};
    uint8_t bufferIn[] = {0, 0};   
   
    if (HAL_SPI_Transmit(&flashSPIh, bufferOut, sizeof(bufferOut), 1000) !=HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       }
    if (HAL_SPI_Receive(&flashSPIh, bufferIn, sizeof(bufferIn), 1000) != HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       }
    FLASH_CS_HIGH();
    return bufferIn[0];
}
sendWriteEnable ():
 
This function sets the Write Enable Latch (WEL) bit in the status register to 1. The WEL bit must be set prior to every Page Program, Sector Erase, Block Erase, Chip Erase and Write Status Register instruction. The write enable is entered by transmitting the command CMD_WREN (0x06).
#define CMD_WREN  0x06
void  sendWriteEnable()
{
    FLASH_CS_LOW();
    uint8_t bufferOut[] = {CMD_WREN};
    if (HAL_SPI_Transmit(&flashSPIh, bufferOut, sizeof(bufferOut), 1000) !=HAL_OK)
   {
       /* Transfer error in transmission process */
     Error_Handler();
   }
    FLASH_CS_HIGH();
}
writeStatusRegister (uint8_t command, uint8_t value) :
 
This function writes the content of the buffer passed as a parameter to the Flash Status register. A write enable instruction must be previously executed for the device to accept the write status register instruction.
 
static void writeStatusRegister(uint8_t command, uint8_t value)
{
    FLASH_CS_LOW();
    uint8_t bufferOut[2];
    bufferOut[0] = command;
    bufferOut[1] = value;
       if (HAL_SPI_Transmit(&flashSPIh, bufferOut, sizeof(bufferOut), 1000) !=HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       } 
    FLASH_CS_HIGH();
}
sendSectorErase (uint32_t address24):
 
This function sets all memory within a specified sector (4K-bytes) to erased state of all 1s (0xFF). A write enable instruction must be executed before the device will accept the Sector Erase Instruction, the command CMD_SE  0x20 is sent followed by the 24-bit sector address.
#define CMD_SE 0x20
void sendSectorErase(uint32_t address24)
{
    FLASH_CS_LOW();
    uint8_t bufferOut[4]; 
    bufferOut[0] = CMD_SE;
    bufferOut[1] = (address24 >> 16) & 0xFF;
    bufferOut[2] = (address24 >> 8) & 0xFF;
    bufferOut[3] = address24 & 0xFF;  
       if (HAL_SPI_Transmit(&flashSPIh, bufferOut, sizeof(bufferOut), 1000) !=HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       } 
    FLASH_CS_HIGH();   
}
sendPageProgram (uint32_t address24, const uint8_t* data, uint32_t length):
 
This function allows any 8bit data buffer to be written in a page (256 bytes long) that has been previously erased (0xFF). The instruction is initiated bydriving the CS pin low then by sending the CMD_PP (0x02) followed by a 24-bit address (A23-A0) and then by sending at least one data byte.
#define CMD_PP  0x02
void sendPageProgram(uint32_t address24, constuint8_t* data, uint32_t length)
{
    FLASH_CS_LOW(); 
    uint8_t bufferOut[4]; 
    bufferOut[0] = CMD_PP;
    bufferOut[1] = (address24 >> 16) & 0xFF;
    bufferOut[2] = (address24 >> 8) & 0xFF;
    bufferOut[3] = address24 & 0xFF;
    if (HAL_SPI_Transmit(&flashSPIh, bufferOut, sizeof(bufferOut), 1000) !=HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       }
    if (HAL_SPI_Transmit(&flashSPIh, (uint8_t *)data, length, 1000) !=HAL_OK)
       {
         /* Transfer error in transmission process */
         Error_Handler();
       }
    FLASH_CS_HIGH();   
}

Please check the Part3 (last part) of this tutorial, where we continue creating driver functions for STM32 microcontroller to interact with external memory device through the SPI peripheral
 
Version history
Last update:
‎2022-06-30 12:35 AM
Updated by: