comparison libs/STM32F10x_StdPeriph_Lib_V3.5.0/Utilities/STM32_EVAL/Common/stm32_eval_spi_flash.c @ 0:c59513fd84fb

Initial commit of STM32 test code.
author Daniel O'Connor <darius@dons.net.au>
date Mon, 03 Oct 2011 21:19:15 +1030
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c59513fd84fb
1 /**
2 ******************************************************************************
3 * @file stm32_eval_spi_flash.c
4 * @author MCD Application Team
5 * @version V4.5.0
6 * @date 07-March-2011
7 * @brief This file provides a set of functions needed to manage the SPI M25Pxxx
8 * FLASH memory mounted on STM32xx-EVAL board (refer to stm32_eval.h
9 * to know about the boards supporting this memory).
10 * It implements a high level communication layer for read and write
11 * from/to this memory. The needed STM32 hardware resources (SPI and
12 * GPIO) are defined in stm32xx_eval.h file, and the initialization is
13 * performed in sFLASH_LowLevel_Init() function declared in stm32xx_eval.c
14 * file.
15 * You can easily tailor this driver to any other development board,
16 * by just adapting the defines for hardware resources and
17 * sFLASH_LowLevel_Init() function.
18 *
19 * +-----------------------------------------------------------+
20 * | Pin assignment |
21 * +-----------------------------+---------------+-------------+
22 * | STM32 SPI Pins | sFLASH | Pin |
23 * +-----------------------------+---------------+-------------+
24 * | sFLASH_CS_PIN | ChipSelect(/S)| 1 |
25 * | sFLASH_SPI_MISO_PIN / MISO | DataOut(Q) | 2 |
26 * | | VCC | 3 (3.3 V)|
27 * | | GND | 4 (0 V) |
28 * | sFLASH_SPI_MOSI_PIN / MOSI | DataIn(D) | 5 |
29 * | sFLASH_SPI_SCK_PIN / SCLK | Clock(C) | 6 |
30 * | | VCC | 7 (3.3 V)|
31 * | | VCC | 8 (3.3 V)|
32 * +-----------------------------+---------------+-------------+
33 ******************************************************************************
34 * @attention
35 *
36 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
37 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
38 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
39 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
40 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
41 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
42 *
43 * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
44 ******************************************************************************
45 */
46
47 /* Includes ------------------------------------------------------------------*/
48 #include "stm32_eval_spi_flash.h"
49
50 /** @addtogroup Utilities
51 * @{
52 */
53
54 /** @addtogroup STM32_EVAL
55 * @{
56 */
57
58 /** @addtogroup Common
59 * @{
60 */
61
62 /** @addtogroup STM32_EVAL_SPI_FLASH
63 * @brief This file includes the M25Pxxx SPI FLASH driver of STM32-EVAL boards.
64 * @{
65 */
66
67 /** @defgroup STM32_EVAL_SPI_FLASH_Private_Types
68 * @{
69 */
70 /**
71 * @}
72 */
73
74
75 /** @defgroup STM32_EVAL_SPI_FLASH_Private_Defines
76 * @{
77 */
78 /**
79 * @}
80 */
81
82 /** @defgroup STM32_EVAL_SPI_FLASH_Private_Macros
83 * @{
84 */
85 /**
86 * @}
87 */
88
89
90 /** @defgroup STM32_EVAL_SPI_FLASH_Private_Variables
91 * @{
92 */
93 /**
94 * @}
95 */
96
97
98 /** @defgroup STM32_EVAL_SPI_FLASH_Private_Function_Prototypes
99 * @{
100 */
101 /**
102 * @}
103 */
104
105
106 /** @defgroup STM32_EVAL_SPI_FLASH_Private_Functions
107 * @{
108 */
109
110 /**
111 * @brief DeInitializes the peripherals used by the SPI FLASH driver.
112 * @param None
113 * @retval None
114 */
115 void sFLASH_DeInit(void)
116 {
117 sFLASH_LowLevel_DeInit();
118 }
119
120 /**
121 * @brief Initializes the peripherals used by the SPI FLASH driver.
122 * @param None
123 * @retval None
124 */
125 void sFLASH_Init(void)
126 {
127 SPI_InitTypeDef SPI_InitStructure;
128
129 sFLASH_LowLevel_Init();
130
131 /*!< Deselect the FLASH: Chip Select high */
132 sFLASH_CS_HIGH();
133
134 /*!< SPI configuration */
135 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
136 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
137 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
138 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
139 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
140 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
141 #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
142 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
143 #else
144 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
145 #endif
146
147 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
148 SPI_InitStructure.SPI_CRCPolynomial = 7;
149 SPI_Init(sFLASH_SPI, &SPI_InitStructure);
150
151 /*!< Enable the sFLASH_SPI */
152 SPI_Cmd(sFLASH_SPI, ENABLE);
153 }
154
155 /**
156 * @brief Erases the specified FLASH sector.
157 * @param SectorAddr: address of the sector to erase.
158 * @retval None
159 */
160 void sFLASH_EraseSector(uint32_t SectorAddr)
161 {
162 /*!< Send write enable instruction */
163 sFLASH_WriteEnable();
164
165 /*!< Sector Erase */
166 /*!< Select the FLASH: Chip Select low */
167 sFLASH_CS_LOW();
168 /*!< Send Sector Erase instruction */
169 sFLASH_SendByte(sFLASH_CMD_SE);
170 /*!< Send SectorAddr high nibble address byte */
171 sFLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
172 /*!< Send SectorAddr medium nibble address byte */
173 sFLASH_SendByte((SectorAddr & 0xFF00) >> 8);
174 /*!< Send SectorAddr low nibble address byte */
175 sFLASH_SendByte(SectorAddr & 0xFF);
176 /*!< Deselect the FLASH: Chip Select high */
177 sFLASH_CS_HIGH();
178
179 /*!< Wait the end of Flash writing */
180 sFLASH_WaitForWriteEnd();
181 }
182
183 /**
184 * @brief Erases the entire FLASH.
185 * @param None
186 * @retval None
187 */
188 void sFLASH_EraseBulk(void)
189 {
190 /*!< Send write enable instruction */
191 sFLASH_WriteEnable();
192
193 /*!< Bulk Erase */
194 /*!< Select the FLASH: Chip Select low */
195 sFLASH_CS_LOW();
196 /*!< Send Bulk Erase instruction */
197 sFLASH_SendByte(sFLASH_CMD_BE);
198 /*!< Deselect the FLASH: Chip Select high */
199 sFLASH_CS_HIGH();
200
201 /*!< Wait the end of Flash writing */
202 sFLASH_WaitForWriteEnd();
203 }
204
205 /**
206 * @brief Writes more than one byte to the FLASH with a single WRITE cycle
207 * (Page WRITE sequence).
208 * @note The number of byte can't exceed the FLASH page size.
209 * @param pBuffer: pointer to the buffer containing the data to be written
210 * to the FLASH.
211 * @param WriteAddr: FLASH's internal address to write to.
212 * @param NumByteToWrite: number of bytes to write to the FLASH, must be equal
213 * or less than "sFLASH_PAGESIZE" value.
214 * @retval None
215 */
216 void sFLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
217 {
218 /*!< Enable the write access to the FLASH */
219 sFLASH_WriteEnable();
220
221 /*!< Select the FLASH: Chip Select low */
222 sFLASH_CS_LOW();
223 /*!< Send "Write to Memory " instruction */
224 sFLASH_SendByte(sFLASH_CMD_WRITE);
225 /*!< Send WriteAddr high nibble address byte to write to */
226 sFLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
227 /*!< Send WriteAddr medium nibble address byte to write to */
228 sFLASH_SendByte((WriteAddr & 0xFF00) >> 8);
229 /*!< Send WriteAddr low nibble address byte to write to */
230 sFLASH_SendByte(WriteAddr & 0xFF);
231
232 /*!< while there is data to be written on the FLASH */
233 while (NumByteToWrite--)
234 {
235 /*!< Send the current byte */
236 sFLASH_SendByte(*pBuffer);
237 /*!< Point on the next byte to be written */
238 pBuffer++;
239 }
240
241 /*!< Deselect the FLASH: Chip Select high */
242 sFLASH_CS_HIGH();
243
244 /*!< Wait the end of Flash writing */
245 sFLASH_WaitForWriteEnd();
246 }
247
248 /**
249 * @brief Writes block of data to the FLASH. In this function, the number of
250 * WRITE cycles are reduced, using Page WRITE sequence.
251 * @param pBuffer: pointer to the buffer containing the data to be written
252 * to the FLASH.
253 * @param WriteAddr: FLASH's internal address to write to.
254 * @param NumByteToWrite: number of bytes to write to the FLASH.
255 * @retval None
256 */
257 void sFLASH_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
258 {
259 uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
260
261 Addr = WriteAddr % sFLASH_SPI_PAGESIZE;
262 count = sFLASH_SPI_PAGESIZE - Addr;
263 NumOfPage = NumByteToWrite / sFLASH_SPI_PAGESIZE;
264 NumOfSingle = NumByteToWrite % sFLASH_SPI_PAGESIZE;
265
266 if (Addr == 0) /*!< WriteAddr is sFLASH_PAGESIZE aligned */
267 {
268 if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
269 {
270 sFLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
271 }
272 else /*!< NumByteToWrite > sFLASH_PAGESIZE */
273 {
274 while (NumOfPage--)
275 {
276 sFLASH_WritePage(pBuffer, WriteAddr, sFLASH_SPI_PAGESIZE);
277 WriteAddr += sFLASH_SPI_PAGESIZE;
278 pBuffer += sFLASH_SPI_PAGESIZE;
279 }
280
281 sFLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
282 }
283 }
284 else /*!< WriteAddr is not sFLASH_PAGESIZE aligned */
285 {
286 if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
287 {
288 if (NumOfSingle > count) /*!< (NumByteToWrite + WriteAddr) > sFLASH_PAGESIZE */
289 {
290 temp = NumOfSingle - count;
291
292 sFLASH_WritePage(pBuffer, WriteAddr, count);
293 WriteAddr += count;
294 pBuffer += count;
295
296 sFLASH_WritePage(pBuffer, WriteAddr, temp);
297 }
298 else
299 {
300 sFLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
301 }
302 }
303 else /*!< NumByteToWrite > sFLASH_PAGESIZE */
304 {
305 NumByteToWrite -= count;
306 NumOfPage = NumByteToWrite / sFLASH_SPI_PAGESIZE;
307 NumOfSingle = NumByteToWrite % sFLASH_SPI_PAGESIZE;
308
309 sFLASH_WritePage(pBuffer, WriteAddr, count);
310 WriteAddr += count;
311 pBuffer += count;
312
313 while (NumOfPage--)
314 {
315 sFLASH_WritePage(pBuffer, WriteAddr, sFLASH_SPI_PAGESIZE);
316 WriteAddr += sFLASH_SPI_PAGESIZE;
317 pBuffer += sFLASH_SPI_PAGESIZE;
318 }
319
320 if (NumOfSingle != 0)
321 {
322 sFLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
323 }
324 }
325 }
326 }
327
328 /**
329 * @brief Reads a block of data from the FLASH.
330 * @param pBuffer: pointer to the buffer that receives the data read from the FLASH.
331 * @param ReadAddr: FLASH's internal address to read from.
332 * @param NumByteToRead: number of bytes to read from the FLASH.
333 * @retval None
334 */
335 void sFLASH_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
336 {
337 /*!< Select the FLASH: Chip Select low */
338 sFLASH_CS_LOW();
339
340 /*!< Send "Read from Memory " instruction */
341 sFLASH_SendByte(sFLASH_CMD_READ);
342
343 /*!< Send ReadAddr high nibble address byte to read from */
344 sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
345 /*!< Send ReadAddr medium nibble address byte to read from */
346 sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
347 /*!< Send ReadAddr low nibble address byte to read from */
348 sFLASH_SendByte(ReadAddr & 0xFF);
349
350 while (NumByteToRead--) /*!< while there is data to be read */
351 {
352 /*!< Read a byte from the FLASH */
353 *pBuffer = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
354 /*!< Point to the next location where the byte read will be saved */
355 pBuffer++;
356 }
357
358 /*!< Deselect the FLASH: Chip Select high */
359 sFLASH_CS_HIGH();
360 }
361
362 /**
363 * @brief Reads FLASH identification.
364 * @param None
365 * @retval FLASH identification
366 */
367 uint32_t sFLASH_ReadID(void)
368 {
369 uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
370
371 /*!< Select the FLASH: Chip Select low */
372 sFLASH_CS_LOW();
373
374 /*!< Send "RDID " instruction */
375 sFLASH_SendByte(0x9F);
376
377 /*!< Read a byte from the FLASH */
378 Temp0 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
379
380 /*!< Read a byte from the FLASH */
381 Temp1 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
382
383 /*!< Read a byte from the FLASH */
384 Temp2 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
385
386 /*!< Deselect the FLASH: Chip Select high */
387 sFLASH_CS_HIGH();
388
389 Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
390
391 return Temp;
392 }
393
394 /**
395 * @brief Initiates a read data byte (READ) sequence from the Flash.
396 * This is done by driving the /CS line low to select the device, then the READ
397 * instruction is transmitted followed by 3 bytes address. This function exit
398 * and keep the /CS line low, so the Flash still being selected. With this
399 * technique the whole content of the Flash is read with a single READ instruction.
400 * @param ReadAddr: FLASH's internal address to read from.
401 * @retval None
402 */
403 void sFLASH_StartReadSequence(uint32_t ReadAddr)
404 {
405 /*!< Select the FLASH: Chip Select low */
406 sFLASH_CS_LOW();
407
408 /*!< Send "Read from Memory " instruction */
409 sFLASH_SendByte(sFLASH_CMD_READ);
410
411 /*!< Send the 24-bit address of the address to read from -------------------*/
412 /*!< Send ReadAddr high nibble address byte */
413 sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
414 /*!< Send ReadAddr medium nibble address byte */
415 sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
416 /*!< Send ReadAddr low nibble address byte */
417 sFLASH_SendByte(ReadAddr & 0xFF);
418 }
419
420 /**
421 * @brief Reads a byte from the SPI Flash.
422 * @note This function must be used only if the Start_Read_Sequence function
423 * has been previously called.
424 * @param None
425 * @retval Byte Read from the SPI Flash.
426 */
427 uint8_t sFLASH_ReadByte(void)
428 {
429 return (sFLASH_SendByte(sFLASH_DUMMY_BYTE));
430 }
431
432 /**
433 * @brief Sends a byte through the SPI interface and return the byte received
434 * from the SPI bus.
435 * @param byte: byte to send.
436 * @retval The value of the received byte.
437 */
438 uint8_t sFLASH_SendByte(uint8_t byte)
439 {
440 /*!< Loop while DR register in not emplty */
441 while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
442
443 /*!< Send byte through the SPI1 peripheral */
444 SPI_I2S_SendData(sFLASH_SPI, byte);
445
446 /*!< Wait to receive a byte */
447 while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
448
449 /*!< Return the byte read from the SPI bus */
450 return SPI_I2S_ReceiveData(sFLASH_SPI);
451 }
452
453 /**
454 * @brief Sends a Half Word through the SPI interface and return the Half Word
455 * received from the SPI bus.
456 * @param HalfWord: Half Word to send.
457 * @retval The value of the received Half Word.
458 */
459 uint16_t sFLASH_SendHalfWord(uint16_t HalfWord)
460 {
461 /*!< Loop while DR register in not emplty */
462 while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
463
464 /*!< Send Half Word through the sFLASH peripheral */
465 SPI_I2S_SendData(sFLASH_SPI, HalfWord);
466
467 /*!< Wait to receive a Half Word */
468 while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
469
470 /*!< Return the Half Word read from the SPI bus */
471 return SPI_I2S_ReceiveData(sFLASH_SPI);
472 }
473
474 /**
475 * @brief Enables the write access to the FLASH.
476 * @param None
477 * @retval None
478 */
479 void sFLASH_WriteEnable(void)
480 {
481 /*!< Select the FLASH: Chip Select low */
482 sFLASH_CS_LOW();
483
484 /*!< Send "Write Enable" instruction */
485 sFLASH_SendByte(sFLASH_CMD_WREN);
486
487 /*!< Deselect the FLASH: Chip Select high */
488 sFLASH_CS_HIGH();
489 }
490
491 /**
492 * @brief Polls the status of the Write In Progress (WIP) flag in the FLASH's
493 * status register and loop until write opertaion has completed.
494 * @param None
495 * @retval None
496 */
497 void sFLASH_WaitForWriteEnd(void)
498 {
499 uint8_t flashstatus = 0;
500
501 /*!< Select the FLASH: Chip Select low */
502 sFLASH_CS_LOW();
503
504 /*!< Send "Read Status Register" instruction */
505 sFLASH_SendByte(sFLASH_CMD_RDSR);
506
507 /*!< Loop as long as the memory is busy with a write cycle */
508 do
509 {
510 /*!< Send a dummy byte to generate the clock needed by the FLASH
511 and put the value of the status register in FLASH_Status variable */
512 flashstatus = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
513
514 }
515 while ((flashstatus & sFLASH_WIP_FLAG) == SET); /* Write in progress */
516
517 /*!< Deselect the FLASH: Chip Select high */
518 sFLASH_CS_HIGH();
519 }
520
521 /**
522 * @}
523 */
524
525 /**
526 * @}
527 */
528
529 /**
530 * @}
531 */
532
533 /**
534 * @}
535 */
536
537 /**
538 * @}
539 */
540
541 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/