stm32_eval_spi_flash.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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. /* Includes ------------------------------------------------------------------*/
  47. #include "stm32_eval_spi_flash.h"
  48. #include "stm32f10x_spi.h"
  49. /** @addtogroup Utilities
  50. * @{
  51. */
  52. /** @addtogroup STM32_EVAL
  53. * @{
  54. */
  55. /** @addtogroup Common
  56. * @{
  57. */
  58. /** @addtogroup STM32_EVAL_SPI_FLASH
  59. * @brief This file includes the M25Pxxx SPI FLASH driver of STM32-EVAL boards.
  60. * @{
  61. */
  62. /** @defgroup STM32_EVAL_SPI_FLASH_Private_Types
  63. * @{
  64. */
  65. /**
  66. * @}
  67. */
  68. /** @defgroup STM32_EVAL_SPI_FLASH_Private_Defines
  69. * @{
  70. */
  71. /**
  72. * @}
  73. */
  74. /** @defgroup STM32_EVAL_SPI_FLASH_Private_Macros
  75. * @{
  76. */
  77. /**
  78. * @}
  79. */
  80. /** @defgroup STM32_EVAL_SPI_FLASH_Private_Variables
  81. * @{
  82. */
  83. /**
  84. * @}
  85. */
  86. /** @defgroup STM32_EVAL_SPI_FLASH_Private_Function_Prototypes
  87. * @{
  88. */
  89. /**
  90. * @}
  91. */
  92. /** @defgroup STM32_EVAL_SPI_FLASH_Private_Functions
  93. * @{
  94. */
  95. /**
  96. * @brief DeInitializes the peripherals used by the SPI FLASH driver.
  97. * @param None
  98. * @retval None
  99. */
  100. void sFLASH_LowLevel_DeInit(void)
  101. {
  102. GPIO_InitTypeDef GPIO_InitStructure;
  103. /*!< Disable the sFLASH_SPI */
  104. SPI_Cmd(sFLASH_SPI, DISABLE);
  105. /*!< DeInitializes the sFLASH_SPI */
  106. SPI_I2S_DeInit(sFLASH_SPI);
  107. /*!< sFLASH_SPI Periph clock disable */
  108. RCC_APB2PeriphClockCmd(sFLASH_SPI_CLK, DISABLE);
  109. /*!< Configure sFLASH_SPI pins: SCK */
  110. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN;
  111. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  112. GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
  113. /*!< Configure sFLASH_SPI pins: MISO */
  114. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MISO_PIN;
  115. GPIO_Init(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
  116. /*!< Configure sFLASH_SPI pins: MOSI */
  117. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MOSI_PIN;
  118. GPIO_Init(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
  119. /*!< Configure sFLASH_CS_PIN pin: sFLASH Card CS pin */
  120. GPIO_InitStructure.GPIO_Pin = sFLASH_CS_PIN;
  121. GPIO_Init(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure);
  122. }
  123. /**
  124. * @brief Initializes the peripherals used by the SPI FLASH driver.
  125. * @param None
  126. * @retval None
  127. */
  128. void sFLASH_LowLevel_Init(void)
  129. {
  130. GPIO_InitTypeDef GPIO_InitStructure;
  131. /*!< sFLASH_SPI_CS_GPIO, sFLASH_SPI_MOSI_GPIO, sFLASH_SPI_MISO_GPIO
  132. and sFLASH_SPI_SCK_GPIO Periph clock enable */
  133. RCC_APB2PeriphClockCmd(sFLASH_CS_GPIO_CLK | sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK |
  134. sFLASH_SPI_SCK_GPIO_CLK, ENABLE);
  135. /*!< sFLASH_SPI Periph clock enable */
  136. RCC_APB2PeriphClockCmd(sFLASH_SPI_CLK, ENABLE);
  137. /*!< Configure sFLASH_SPI pins: SCK */
  138. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN;
  139. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  140. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  141. GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
  142. /*!< Configure sFLASH_SPI pins: MOSI */
  143. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MOSI_PIN;
  144. GPIO_Init(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
  145. /*!< Configure sFLASH_SPI pins: MISO */
  146. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MISO_PIN;
  147. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  148. GPIO_Init(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
  149. /*!< Configure sFLASH_CS_PIN pin: sFLASH Card CS pin */
  150. GPIO_InitStructure.GPIO_Pin = sFLASH_CS_PIN;
  151. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  152. GPIO_Init(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure);
  153. }
  154. /**
  155. * @brief DeInitializes the peripherals used by the SPI FLASH driver.
  156. * @param None
  157. * @retval None
  158. */
  159. void sFLASH_DeInit(void)
  160. {
  161. sFLASH_LowLevel_DeInit();
  162. }
  163. /**
  164. * @brief Initializes the peripherals used by the SPI FLASH driver.
  165. * @param None
  166. * @retval None
  167. */
  168. void sFLASH_Init(void)
  169. {
  170. SPI_InitTypeDef SPI_InitStructure;
  171. sFLASH_LowLevel_Init();
  172. /*!< Deselect the FLASH: Chip Select high */
  173. sFLASH_CS_HIGH();
  174. /*!< SPI configuration */
  175. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  176. SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  177. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  178. SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  179. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  180. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  181. #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
  182. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
  183. #else
  184. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  185. #endif
  186. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  187. SPI_InitStructure.SPI_CRCPolynomial = 7;
  188. SPI_Init(sFLASH_SPI, &SPI_InitStructure);
  189. /*!< Enable the sFLASH_SPI */
  190. SPI_Cmd(sFLASH_SPI, ENABLE);
  191. }
  192. /**
  193. * @brief Erases the specified FLASH sector.
  194. * @param SectorAddr: address of the sector to erase.
  195. * @retval None
  196. */
  197. void sFLASH_EraseSector(uint32_t SectorAddr)
  198. {
  199. /*!< Send write enable instruction */
  200. sFLASH_WriteEnable();
  201. /*!< Sector Erase */
  202. /*!< Select the FLASH: Chip Select low */
  203. sFLASH_CS_LOW();
  204. /*!< Send Sector Erase instruction */
  205. sFLASH_SendByte(sFLASH_CMD_SE);
  206. /*!< Send SectorAddr high nibble address byte */
  207. sFLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  208. /*!< Send SectorAddr medium nibble address byte */
  209. sFLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  210. /*!< Send SectorAddr low nibble address byte */
  211. sFLASH_SendByte(SectorAddr & 0xFF);
  212. /*!< Deselect the FLASH: Chip Select high */
  213. sFLASH_CS_HIGH();
  214. /*!< Wait the end of Flash writing */
  215. sFLASH_WaitForWriteEnd();
  216. }
  217. /**
  218. * @brief Erases the entire FLASH.
  219. * @param None
  220. * @retval None
  221. */
  222. void sFLASH_EraseBulk(void)
  223. {
  224. /*!< Send write enable instruction */
  225. sFLASH_WriteEnable();
  226. /*!< Bulk Erase */
  227. /*!< Select the FLASH: Chip Select low */
  228. sFLASH_CS_LOW();
  229. /*!< Send Bulk Erase instruction */
  230. sFLASH_SendByte(sFLASH_CMD_BE);
  231. /*!< Deselect the FLASH: Chip Select high */
  232. sFLASH_CS_HIGH();
  233. /*!< Wait the end of Flash writing */
  234. sFLASH_WaitForWriteEnd();
  235. }
  236. /**
  237. * @brief Writes more than one byte to the FLASH with a single WRITE cycle
  238. * (Page WRITE sequence).
  239. * @note The number of byte can't exceed the FLASH page size.
  240. * @param pBuffer: pointer to the buffer containing the data to be written
  241. * to the FLASH.
  242. * @param WriteAddr: FLASH's internal address to write to.
  243. * @param NumByteToWrite: number of bytes to write to the FLASH, must be equal
  244. * or less than "sFLASH_PAGESIZE" value.
  245. * @retval None
  246. */
  247. void sFLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
  248. {
  249. /*!< Enable the write access to the FLASH */
  250. sFLASH_WriteEnable();
  251. /*!< Select the FLASH: Chip Select low */
  252. sFLASH_CS_LOW();
  253. /*!< Send "Write to Memory " instruction */
  254. sFLASH_SendByte(sFLASH_CMD_WRITE);
  255. /*!< Send WriteAddr high nibble address byte to write to */
  256. sFLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  257. /*!< Send WriteAddr medium nibble address byte to write to */
  258. sFLASH_SendByte((WriteAddr & 0xFF00) >> 8);
  259. /*!< Send WriteAddr low nibble address byte to write to */
  260. sFLASH_SendByte(WriteAddr & 0xFF);
  261. /*!< while there is data to be written on the FLASH */
  262. while (NumByteToWrite--)
  263. {
  264. /*!< Send the current byte */
  265. sFLASH_SendByte(*pBuffer);
  266. /*!< Point on the next byte to be written */
  267. pBuffer++;
  268. }
  269. /*!< Deselect the FLASH: Chip Select high */
  270. sFLASH_CS_HIGH();
  271. /*!< Wait the end of Flash writing */
  272. sFLASH_WaitForWriteEnd();
  273. }
  274. /**
  275. * @brief Writes block of data to the FLASH. In this function, the number of
  276. * WRITE cycles are reduced, using Page WRITE sequence.
  277. * @param pBuffer: pointer to the buffer containing the data to be written
  278. * to the FLASH.
  279. * @param WriteAddr: FLASH's internal address to write to.
  280. * @param NumByteToWrite: number of bytes to write to the FLASH.
  281. * @retval None
  282. */
  283. void sFLASH_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
  284. {
  285. uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
  286. Addr = WriteAddr % sFLASH_SPI_PAGESIZE;
  287. count = sFLASH_SPI_PAGESIZE - Addr;
  288. NumOfPage = NumByteToWrite / sFLASH_SPI_PAGESIZE;
  289. NumOfSingle = NumByteToWrite % sFLASH_SPI_PAGESIZE;
  290. if (Addr == 0) /*!< WriteAddr is sFLASH_PAGESIZE aligned */
  291. {
  292. if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
  293. {
  294. sFLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
  295. }
  296. else /*!< NumByteToWrite > sFLASH_PAGESIZE */
  297. {
  298. while (NumOfPage--)
  299. {
  300. sFLASH_WritePage(pBuffer, WriteAddr, sFLASH_SPI_PAGESIZE);
  301. WriteAddr += sFLASH_SPI_PAGESIZE;
  302. pBuffer += sFLASH_SPI_PAGESIZE;
  303. }
  304. sFLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
  305. }
  306. }
  307. else /*!< WriteAddr is not sFLASH_PAGESIZE aligned */
  308. {
  309. if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
  310. {
  311. if (NumOfSingle > count) /*!< (NumByteToWrite + WriteAddr) > sFLASH_PAGESIZE */
  312. {
  313. temp = NumOfSingle - count;
  314. sFLASH_WritePage(pBuffer, WriteAddr, count);
  315. WriteAddr += count;
  316. pBuffer += count;
  317. sFLASH_WritePage(pBuffer, WriteAddr, temp);
  318. }
  319. else
  320. {
  321. sFLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
  322. }
  323. }
  324. else /*!< NumByteToWrite > sFLASH_PAGESIZE */
  325. {
  326. NumByteToWrite -= count;
  327. NumOfPage = NumByteToWrite / sFLASH_SPI_PAGESIZE;
  328. NumOfSingle = NumByteToWrite % sFLASH_SPI_PAGESIZE;
  329. sFLASH_WritePage(pBuffer, WriteAddr, count);
  330. WriteAddr += count;
  331. pBuffer += count;
  332. while (NumOfPage--)
  333. {
  334. sFLASH_WritePage(pBuffer, WriteAddr, sFLASH_SPI_PAGESIZE);
  335. WriteAddr += sFLASH_SPI_PAGESIZE;
  336. pBuffer += sFLASH_SPI_PAGESIZE;
  337. }
  338. if (NumOfSingle != 0)
  339. {
  340. sFLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
  341. }
  342. }
  343. }
  344. }
  345. /**
  346. * @brief Reads a block of data from the FLASH.
  347. * @param pBuffer: pointer to the buffer that receives the data read from the FLASH.
  348. * @param ReadAddr: FLASH's internal address to read from.
  349. * @param NumByteToRead: number of bytes to read from the FLASH.
  350. * @retval None
  351. */
  352. void sFLASH_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
  353. {
  354. /*!< Select the FLASH: Chip Select low */
  355. sFLASH_CS_LOW();
  356. /*!< Send "Read from Memory " instruction */
  357. sFLASH_SendByte(sFLASH_CMD_READ);
  358. /*!< Send ReadAddr high nibble address byte to read from */
  359. sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  360. /*!< Send ReadAddr medium nibble address byte to read from */
  361. sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  362. /*!< Send ReadAddr low nibble address byte to read from */
  363. sFLASH_SendByte(ReadAddr & 0xFF);
  364. while (NumByteToRead--) /*!< while there is data to be read */
  365. {
  366. /*!< Read a byte from the FLASH */
  367. *pBuffer = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
  368. /*!< Point to the next location where the byte read will be saved */
  369. pBuffer++;
  370. }
  371. /*!< Deselect the FLASH: Chip Select high */
  372. sFLASH_CS_HIGH();
  373. }
  374. /**
  375. * @brief Reads FLASH identification.
  376. * @param None
  377. * @retval FLASH identification
  378. */
  379. uint32_t sFLASH_ReadID(void)
  380. {
  381. uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
  382. /*!< Select the FLASH: Chip Select low */
  383. sFLASH_CS_LOW();
  384. /*!< Send "RDID " instruction */
  385. sFLASH_SendByte(0x9F);
  386. /*!< Read a byte from the FLASH */
  387. Temp0 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
  388. /*!< Read a byte from the FLASH */
  389. Temp1 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
  390. /*!< Read a byte from the FLASH */
  391. Temp2 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
  392. /*!< Deselect the FLASH: Chip Select high */
  393. sFLASH_CS_HIGH();
  394. Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
  395. return Temp;
  396. }
  397. /**
  398. * @brief Initiates a read data byte (READ) sequence from the Flash.
  399. * This is done by driving the /CS line low to select the device, then the READ
  400. * instruction is transmitted followed by 3 bytes address. This function exit
  401. * and keep the /CS line low, so the Flash still being selected. With this
  402. * technique the whole content of the Flash is read with a single READ instruction.
  403. * @param ReadAddr: FLASH's internal address to read from.
  404. * @retval None
  405. */
  406. void sFLASH_StartReadSequence(uint32_t ReadAddr)
  407. {
  408. /*!< Select the FLASH: Chip Select low */
  409. sFLASH_CS_LOW();
  410. /*!< Send "Read from Memory " instruction */
  411. sFLASH_SendByte(sFLASH_CMD_READ);
  412. /*!< Send the 24-bit address of the address to read from -------------------*/
  413. /*!< Send ReadAddr high nibble address byte */
  414. sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  415. /*!< Send ReadAddr medium nibble address byte */
  416. sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  417. /*!< Send ReadAddr low nibble address byte */
  418. sFLASH_SendByte(ReadAddr & 0xFF);
  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. * @brief Sends a byte through the SPI interface and return the byte received
  433. * from the SPI bus.
  434. * @param byte: byte to send.
  435. * @retval The value of the received byte.
  436. */
  437. uint8_t sFLASH_SendByte(uint8_t byte)
  438. {
  439. /*!< Loop while DR register in not emplty */
  440. while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
  441. /*!< Send byte through the SPI1 peripheral */
  442. SPI_I2S_SendData(sFLASH_SPI, byte);
  443. /*!< Wait to receive a byte */
  444. while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
  445. /*!< Return the byte read from the SPI bus */
  446. return SPI_I2S_ReceiveData(sFLASH_SPI);
  447. }
  448. /**
  449. * @brief Sends a Half Word through the SPI interface and return the Half Word
  450. * received from the SPI bus.
  451. * @param HalfWord: Half Word to send.
  452. * @retval The value of the received Half Word.
  453. */
  454. uint16_t sFLASH_SendHalfWord(uint16_t HalfWord)
  455. {
  456. /*!< Loop while DR register in not emplty */
  457. while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
  458. /*!< Send Half Word through the sFLASH peripheral */
  459. SPI_I2S_SendData(sFLASH_SPI, HalfWord);
  460. /*!< Wait to receive a Half Word */
  461. while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
  462. /*!< Return the Half Word read from the SPI bus */
  463. return SPI_I2S_ReceiveData(sFLASH_SPI);
  464. }
  465. /**
  466. * @brief Enables the write access to the FLASH.
  467. * @param None
  468. * @retval None
  469. */
  470. void sFLASH_WriteEnable(void)
  471. {
  472. /*!< Select the FLASH: Chip Select low */
  473. sFLASH_CS_LOW();
  474. /*!< Send "Write Enable" instruction */
  475. sFLASH_SendByte(sFLASH_CMD_WREN);
  476. /*!< Deselect the FLASH: Chip Select high */
  477. sFLASH_CS_HIGH();
  478. }
  479. /**
  480. * @brief Polls the status of the Write In Progress (WIP) flag in the FLASH's
  481. * status register and loop until write opertaion has completed.
  482. * @param None
  483. * @retval None
  484. */
  485. void sFLASH_WaitForWriteEnd(void)
  486. {
  487. uint8_t flashstatus = 0;
  488. /*!< Select the FLASH: Chip Select low */
  489. sFLASH_CS_LOW();
  490. /*!< Send "Read Status Register" instruction */
  491. sFLASH_SendByte(sFLASH_CMD_RDSR);
  492. /*!< Loop as long as the memory is busy with a write cycle */
  493. do
  494. {
  495. /*!< Send a dummy byte to generate the clock needed by the FLASH
  496. and put the value of the status register in FLASH_Status variable */
  497. flashstatus = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
  498. }
  499. while ((flashstatus & sFLASH_WIP_FLAG) == SET); /* Write in progress */
  500. /*!< Deselect the FLASH: Chip Select high */
  501. sFLASH_CS_HIGH();
  502. }
  503. /**
  504. * @}
  505. */
  506. /**
  507. * @}
  508. */
  509. /**
  510. * @}
  511. */
  512. /**
  513. * @}
  514. */
  515. /**
  516. * @}
  517. */
  518. /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/