This section is to demostrate how the MCU / Host can write data to the SPI flash connected with LT768x.
Levetop's demo board has an 128Mb nor-flash connected with LT768x. Users may write data to the the flash chip through LT768x. Before writing data to the flash chip, the designated area must be eased first. The data in the erased area of the flash chip will become 0xFF. Please note that writing data to non-0xFF area will be failed. Users may check out Winbond datasheet for more information about the nor-flash chip charateristics.
In the demo code, a set of 256 bytes (a page) data is assigned to a buffer array, pBuf.
u8 pBuf[256] = {0xE0, 0xFF.............0xE0, 0xFF};
In order to make it easier to understand, 0xFFE0, a 16bit data of yellow color (R5 G6 R5) is used as an example. In addition, when writing data to the flash chip, the writing sequence is LSB first, and then MSB. Therefore, the data in the buffer array is arranged as {0xE0, 0xFF...}
Also, because the panel resolution in this example is 800x480, it means a full screen is 800x480x2 = 768Kbytes. The pBuf data is therefore written to the flash chip repeatedly to fill in a full screen size.
for(int i = 0; i <768000; i += 256)
{
W25QXX_Write_Page(pBuf, i, 256); //Write 256bytes at a time
}
Finally, a DMA instruction is used to retrieve the data in the flash chip, and write to the LT768x SDRAM for displaying.
LT768_DMA_24bit_Block(1,0,0,0,LCD_XSIZE_TFT, LCD_YSIZE_TFT, LCD_XSIZE_TFT,0);
The code is listed below:
/*----------------------------------------------------------------------------------------*/
/* Function: MCU_Write_Flash */
/* */
/* Parameters: None */
/* Returns: None */
/* Description: MCU write data to flash through LT768x */
/*----------------------------------------------------------------------------------------*/
void MCU_Write_Flash(void)
{
//Test Data: Yellow color -> 0xFFE0
u8 pBuf[256] = {
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,
0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE0,0xFF
};
Select_Main_Window_16bpp(); // Set main window color depth
Main_Image_Start_Address(LAYER_0); // Set main window start address - Display layer
Main_Image_Width(LCD_XSIZE_TFT); // Set main window width
Main_Window_Start_XY(0,0); // Set main window start coordinate
Canvas_Image_Start_address(LAYER_0); // Set canvas start address
Canvas_image_width(LCD_XSIZE_TFT); // Set canvas width
Active_Window_XY(0,0); // Set active window start coordinate
Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); // Set active window area
// Display a full black screen
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, Black);
// Initialize SPI interface - the one connected to the Flash
LT768_SPI_Init(1,1);
// Erase SPI Flash chip - This may take some time
W25qxx_Erase_Chip();
// Write pBuf to SPI Flash - Following example is for 800x480 display, the full data bytes = 800x480x2 = 768000
// Write a full screen of yellow color (0xFFE0)
for(int i = 0; i <768000; i += 256)
{
W25QXX_Write_Page(pBuf, i, 256); //Write 256bytes at a time
}
// Use DMA function to retrieve the flash data and display it onto the panel
LT768_DMA_24bit_Block(1,0,0,0,LCD_XSIZE_TFT, LCD_YSIZE_TFT, LCD_XSIZE_TFT,0);
}
//--------------------------------------------------- MCU write Flash -------------------------------------------------------------
// Flash Instruction Table
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_FastReadDual 0x3B
#define W25X_PageProgram 0x02
#define W25X_BlockErase32KB 0x52
#define W25X_BlockErase64KB 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_PowerDown 0xB9
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F
/*---------------------------------------------------------------------------------------*/
/* Function: W25QXX_ReadSR */
/* */
/* Parameters: None */
/* Returns: Byte */
/* BIT 7 6 5 4 3 2 1 0 */
/* SPR RV TB BP2 BP1 BP0 WEL BUSY */
/* Default: 0x00 */
/* Description: Read Status Register of the SPI Flash */
/*---------------------------------------------------------------------------------------*/
uint8_t W25QXX_ReadSR(void)
{
uint8_t byte=0;
nSS_Active(); // Select device
SPI_Master_FIFO_Data_Put(W25X_ReadStatusReg); // Issue the "read status register" insturction
byte=SPI_Master_FIFO_Data_Put(0xff); // Read a byte
nSS_Inactive(); // Disselect device
return byte;
}
/*---------------------------------------------------------------------------------------*/
/* Function: W25QXX_Write_Enable */
/* */
/* Parameters: None */
/* Returns: None */
/* Description: Enable "Write to Flash" */
/*---------------------------------------------------------------------------------------*/
void W25QXX_Write_Enable(void)
{
nSS_Active(); // Select device
SPI_Master_FIFO_Data_Put(W25X_WriteEnable); // Issue "Enable Write to Flash" instruction
nSS_Inactive(); // Disselect device
}
/*---------------------------------------------------------------------------------------*/
/* Function: W25QXX_Wait_Busy */
/* */
/* Parameters: None */
/* Returns: None */
/* Description: Wait while the flash is busy */
/*---------------------------------------------------------------------------------------*/
void W25QXX_Wait_Busy(void)
{
while((W25QXX_ReadSR()&0x01)==0x01) ; // Wait while the flash is busy
}
/*---------------------------------------------------------------------------------------*/
/* Function: W25QXX_Erase_Chip */
/* */
/* Parameters: None */
/* Returns: None */
/* Description: Erase the whole flash chip */
/*---------------------------------------------------------------------------------------*/
void W25QXX_Erase_Chip(void)
{
W25QXX_Write_Enable(); // Enable "write to flash"
W25QXX_Wait_Busy(); // Wait while the flash is busy
nSS_Active(); // Select device
SPI_Master_FIFO_Data_Put(W25X_ChipErase); // Issue "Erase Chip" instruction
nSS_Inactive(); // Disselect device
W25QXX_Wait_Busy(); // Wait till the "erase" operation is done
}
/*---------------------------------------------------------------------------------------*/
/* Function: W25QXX_Write_Page */
/* */
/* Parameters: */
/* pBuffer: Buffer for the data to be written to the flash */
/* WriteAddr: Starting flash address to wirte data */
/* NumByteToWrite: Amount of data to write */
/* Returns: None */
/* Description: To write data to Flah */
/*---------------------------------------------------------------------------------------*/
void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t i;
W25QXX_Write_Enable(); // Enable "write to flash"
nSS_Active(); // Select device
SPI_Master_FIFO_Data_Put(W25X_PageProgram); // Issue the "write page" instruction
SPI_Master_FIFO_Data_Put((uint8_t)((WriteAddr)>>16)); // Issue the 24bit address
SPI_Master_FIFO_Data_Put((uint8_t)((WriteAddr)>>8));
SPI_Master_FIFO_Data_Put((uint8_t)WriteAddr);
#if STM32_SPI_8
LCD_CmdWrite(0xB8);
SS_RESET;
SPI2_ReadWriteByte(0x80);
#endif
for(i=0;i<NumByteToWrite;i++)
{
#if STM32_SPI_8
SPI2_ReadWriteByte(pBuffer[i]);
#else
LCD_CmdWrite(0xB8);
LCD_DataWrite(pBuffer[i]);
#endif
}
#if STM32_SPI_8
SS_SET;
#endif
nSS_Inactive(); // Disselect device
W25QXX_Wait_Busy(); // Wait till the "write" operation is done
}
The running result is to display a full screen of yellow color.