1 /******************** (C) COPYRIGHT 2007 STMicroelectronics ********************
2 * File Name : spi_flash.c
3 * Author : MCD Application Team
4 * Date First Issued : 02/05/2007
5 * Description : This file provides a set of functions needed to manage the
6 * communication between SPI peripheral and SPI M25P64 FLASH.
7 ********************************************************************************
11 ********************************************************************************
12 * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
13 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
14 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
15 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
16 * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
17 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18 *******************************************************************************/
20 /* Includes ------------------------------------------------------------------*/
21 #include "spi_flash.h"
23 /* Private typedef -----------------------------------------------------------*/
24 #define SPI_FLASH_PageSize 256
26 #define WRITE 0x02 /* Write to Memory instruction */
27 #define WRSR 0x01 /* Write Status Register instruction */
28 #define WREN 0x06 /* Write enable instruction */
30 #define READ 0x03 /* Read from Memory instruction */
31 #define RDSR 0x05 /* Read Status Register instruction */
32 #define RDID 0x9F /* Read identification */
33 #define SE 0xD8 /* Sector Erase instruction */
34 #define BE 0xC7 /* Bulk Erase instruction */
36 #define WIP_Flag 0x01 /* Write In Progress (WIP) flag */
38 #define Dummy_Byte 0xA5
40 /* Private define ------------------------------------------------------------*/
41 /* Private macro -------------------------------------------------------------*/
42 /* Private variables ---------------------------------------------------------*/
43 /* Private function prototypes -----------------------------------------------*/
44 /* Private functions ---------------------------------------------------------*/
46 /*******************************************************************************
47 * Function Name : SPI_FLASH_Init
48 * Description : Initializes the peripherals used by the SPI FLASH driver.
52 *******************************************************************************/
53 void SPI_FLASH_Init(void)
55 SPI_InitTypeDef SPI_InitStructure;
56 GPIO_InitTypeDef GPIO_InitStructure;
58 /* Enable SPI1 and GPIOA clocks */
59 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA, ENABLE);
61 /* Configure SPI1 pins: NSS, SCK, MISO and MOSI */
62 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
63 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
64 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
65 GPIO_Init(GPIOA, &GPIO_InitStructure);
67 /* Configure PA.4 as Output push-pull, used as Flash Chip select */
68 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
69 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
70 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
71 GPIO_Init(GPIOA, &GPIO_InitStructure);
73 /* Deselect the FLASH: Chip Select high */
74 SPI_FLASH_ChipSelect(High);
76 /* SPI1 configuration */
77 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
78 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
79 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
80 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
81 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
82 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
83 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
84 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
85 SPI_InitStructure.SPI_CRCPolynomial = 7;
86 SPI_Init(SPI1, &SPI_InitStructure);
89 SPI_Cmd(SPI1, ENABLE);
92 /*******************************************************************************
93 * Function Name : SPI_FLASH_SectorErase
94 * Description : Erases the specified FLASH sector.
95 * Input : SectorAddr: address of the sector to erase.
98 *******************************************************************************/
99 void SPI_FLASH_SectorErase(u32 SectorAddr)
101 /* Send write enable instruction */
102 SPI_FLASH_WriteEnable();
105 /* Select the FLASH: Chip Select low */
106 SPI_FLASH_ChipSelect(Low);
107 /* Send Sector Erase instruction */
108 SPI_FLASH_SendByte(SE);
109 /* Send SectorAddr high nibble address byte */
110 SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
111 /* Send SectorAddr medium nibble address byte */
112 SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
113 /* Send SectorAddr low nibble address byte */
114 SPI_FLASH_SendByte(SectorAddr & 0xFF);
115 /* Deselect the FLASH: Chip Select high */
116 SPI_FLASH_ChipSelect(High);
118 /* Wait the end of Flash writing */
119 SPI_FLASH_WaitForWriteEnd();
122 /*******************************************************************************
123 * Function Name : SPI_FLASH_BulkErase
124 * Description : Erases the entire FLASH.
128 *******************************************************************************/
129 void SPI_FLASH_BulkErase(void)
131 /* Send write enable instruction */
132 SPI_FLASH_WriteEnable();
135 /* Select the FLASH: Chip Select low */
136 SPI_FLASH_ChipSelect(Low);
137 /* Send Bulk Erase instruction */
138 SPI_FLASH_SendByte(BE);
139 /* Deselect the FLASH: Chip Select high */
140 SPI_FLASH_ChipSelect(High);
142 /* Wait the end of Flash writing */
143 SPI_FLASH_WaitForWriteEnd();
146 /*******************************************************************************
147 * Function Name : SPI_FLASH_PageWrite
148 * Description : Writes more than one byte to the FLASH with a single WRITE
149 * cycle(Page WRITE sequence). The number of byte can't exceed
150 * the FLASH page size.
151 * Input : - pBuffer : pointer to the buffer containing the data to be
152 * written to the FLASH.
153 * - WriteAddr : FLASH's internal address to write to.
154 * - NumByteToWrite : number of bytes to write to the FLASH,
155 * must be equal or less than "SPI_FLASH_PageSize" value.
158 *******************************************************************************/
159 void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
161 /* Enable the write access to the FLASH */
162 SPI_FLASH_WriteEnable();
164 /* Select the FLASH: Chip Select low */
165 SPI_FLASH_ChipSelect(Low);
166 /* Send "Write to Memory " instruction */
167 SPI_FLASH_SendByte(WRITE);
168 /* Send WriteAddr high nibble address byte to write to */
169 SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
170 /* Send WriteAddr medium nibble address byte to write to */
171 SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
172 /* Send WriteAddr low nibble address byte to write to */
173 SPI_FLASH_SendByte(WriteAddr & 0xFF);
175 /* while there is data to be written on the FLASH */
176 while(NumByteToWrite--)
178 /* Send the current byte */
179 SPI_FLASH_SendByte(*pBuffer);
180 /* Point on the next byte to be written */
184 /* Deselect the FLASH: Chip Select high */
185 SPI_FLASH_ChipSelect(High);
187 /* Wait the end of Flash writing */
188 SPI_FLASH_WaitForWriteEnd();
191 /*******************************************************************************
192 * Function Name : SPI_FLASH_BufferWrite
193 * Description : Writes block of data to the FLASH. In this function, the
194 * number of WRITE cycles are reduced, using Page WRITE sequence.
195 * Input : - pBuffer : pointer to the buffer containing the data to be
196 * written to the FLASH.
197 * - WriteAddr : FLASH's internal address to write to.
198 * - NumByteToWrite : number of bytes to write to the FLASH.
201 *******************************************************************************/
202 void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
204 u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
206 Addr = WriteAddr % SPI_FLASH_PageSize;
207 count = SPI_FLASH_PageSize - Addr;
208 NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;
209 NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
211 if(Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned */
213 if(NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
215 SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
217 else /* NumByteToWrite > SPI_FLASH_PageSize */
221 SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
222 WriteAddr += SPI_FLASH_PageSize;
223 pBuffer += SPI_FLASH_PageSize;
226 SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
229 else /* WriteAddr is not SPI_FLASH_PageSize aligned */
231 if(NumOfPage== 0) /* NumByteToWrite < SPI_FLASH_PageSize */
233 if(NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */
235 temp = NumOfSingle - count;
237 SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
241 SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
245 SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
248 else /* NumByteToWrite > SPI_FLASH_PageSize */
250 NumByteToWrite -= count;
251 NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;
252 NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
254 SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
260 SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
261 WriteAddr += SPI_FLASH_PageSize;
262 pBuffer += SPI_FLASH_PageSize;
267 SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
273 /*******************************************************************************
274 * Function Name : SPI_FLASH_BufferRead
275 * Description : Reads a block of data from the FLASH.
276 * Input : - pBuffer : pointer to the buffer that receives the data read
278 * - ReadAddr : FLASH's internal address to read from.
279 * - NumByteToRead : number of bytes to read from the FLASH.
282 *******************************************************************************/
283 void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
285 /* Select the FLASH: Chip Select low */
286 SPI_FLASH_ChipSelect(Low);
288 /* Send "Read from Memory " instruction */
289 SPI_FLASH_SendByte(READ);
291 /* Send ReadAddr high nibble address byte to read from */
292 SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
293 /* Send ReadAddr medium nibble address byte to read from */
294 SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
295 /* Send ReadAddr low nibble address byte to read from */
296 SPI_FLASH_SendByte(ReadAddr & 0xFF);
298 while(NumByteToRead--) /* while there is data to be read */
300 /* Read a byte from the FLASH */
301 *pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
302 /* Point to the next location where the byte read will be saved */
306 /* Deselect the FLASH: Chip Select high */
307 SPI_FLASH_ChipSelect(High);
310 /*******************************************************************************
311 * Function Name : SPI_FLASH_ReadID
312 * Description : Reads FLASH identification.
315 * Return : FLASH identification
316 *******************************************************************************/
317 u32 SPI_FLASH_ReadID(void)
319 u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
321 /* Select the FLASH: Chip Select low */
322 SPI_FLASH_ChipSelect(Low);
324 /* Send "RDID " instruction */
325 SPI_FLASH_SendByte(0x9F);
327 /* Read a byte from the FLASH */
328 Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
330 /* Read a byte from the FLASH */
331 Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
333 /* Read a byte from the FLASH */
334 Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
336 /* Deselect the FLASH: Chip Select high */
337 SPI_FLASH_ChipSelect(High);
339 Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
344 /*******************************************************************************
345 * Function Name : SPI_FLASH_StartReadSequence
346 * Description : Initiates a read data byte (READ) sequence from the Flash.
347 * This is done by driving the /CS line low to select the device,
348 * then the READ instruction is transmitted followed by 3 bytes
349 * address. This function exit and keep the /CS line low, so the
350 * Flash still being selected. With this technique the whole
351 * content of the Flash is read with a single READ instruction.
352 * Input : - ReadAddr : FLASH's internal address to read from.
355 *******************************************************************************/
356 void SPI_FLASH_StartReadSequence(u32 ReadAddr)
358 /* Select the FLASH: Chip Select low */
359 SPI_FLASH_ChipSelect(Low);
361 /* Send "Read from Memory " instruction */
362 SPI_FLASH_SendByte(READ);
364 /* Send the 24-bit address of the address to read from -----------------------*/
365 /* Send ReadAddr high nibble address byte */
366 SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
367 /* Send ReadAddr medium nibble address byte */
368 SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
369 /* Send ReadAddr low nibble address byte */
370 SPI_FLASH_SendByte(ReadAddr & 0xFF);
373 /*******************************************************************************
374 * Function Name : SPI_FLASH_ReadByte
375 * Description : Reads a byte from the SPI Flash.
376 * This function must be used only if the Start_Read_Sequence
377 * function has been previously called.
380 * Return : Byte Read from the SPI Flash.
381 *******************************************************************************/
382 u8 SPI_FLASH_ReadByte(void)
384 return (SPI_FLASH_SendByte(Dummy_Byte));
387 /*******************************************************************************
388 * Function Name : SPI_FLASH_ChipSelect
389 * Description : Selects or deselects the FLASH.
390 * Input : State : level to be applied on the FLASH's ChipSelect pin.
393 *******************************************************************************/
394 void SPI_FLASH_ChipSelect(u8 State)
396 /* Set High or low the chip select line on PA.4 pin */
397 GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)State);
400 /*******************************************************************************
401 * Function Name : SPI_FLASH_SendByte
402 * Description : Sends a byte through the SPI interface and return the byte
403 * received from the SPI bus.
404 * Input : byte : byte to send.
406 * Return : The value of the received byte.
407 *******************************************************************************/
408 u8 SPI_FLASH_SendByte(u8 byte)
410 /* Loop while DR register in not emplty */
411 while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
413 /* Send byte through the SPI1 peripheral */
414 SPI_SendData(SPI1, byte);
416 /* Wait to receive a byte */
417 while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);
419 /* Return the byte read from the SPI bus */
420 return SPI_ReceiveData(SPI1);
423 /*******************************************************************************
424 * Function Name : SPI_FLASH_SendHalfWord
425 * Description : Sends a Half Word through the SPI interface and return the
426 * Half Word received from the SPI bus.
427 * Input : Half Word : Half Word to send.
429 * Return : The value of the received Half Word.
430 *******************************************************************************/
431 u16 SPI_FLASH_SendHalfWord(u16 HalfWord)
433 /* Loop while DR register in not emplty */
434 while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
436 /* Send Half Word through the SPI1 peripheral */
437 SPI_SendData(SPI1, HalfWord);
439 /* Wait to receive a Half Word */
440 while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);
442 /* Return the Half Word read from the SPI bus */
443 return SPI_ReceiveData(SPI1);
446 /*******************************************************************************
447 * Function Name : SPI_FLASH_WriteEnable
448 * Description : Enables the write access to the FLASH.
452 *******************************************************************************/
453 void SPI_FLASH_WriteEnable(void)
455 /* Select the FLASH: Chip Select low */
456 SPI_FLASH_ChipSelect(Low);
458 /* Send "Write Enable" instruction */
459 SPI_FLASH_SendByte(WREN);
461 /* Deselect the FLASH: Chip Select high */
462 SPI_FLASH_ChipSelect(High);
465 /*******************************************************************************
466 * Function Name : SPI_FLASH_WaitForWriteEnd
467 * Description : Polls the status of the Write In Progress (WIP) flag in the
468 * FLASH's status register and loop until write opertaion
473 *******************************************************************************/
474 void SPI_FLASH_WaitForWriteEnd(void)
478 /* Select the FLASH: Chip Select low */
479 SPI_FLASH_ChipSelect(Low);
481 /* Send "Read Status Register" instruction */
482 SPI_FLASH_SendByte(RDSR);
484 /* Loop as long as the memory is busy with a write cycle */
488 /* Send a dummy byte to generate the clock needed by the FLASH
489 and put the value of the status register in FLASH_Status variable */
490 FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);
492 } while((FLASH_Status & WIP_Flag) == SET); /* Write in progress */
494 /* Deselect the FLASH: Chip Select high */
495 SPI_FLASH_ChipSelect(High);
498 /******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/