--- /dev/null
+/**\r
+ ******************************************************************************\r
+ * @file stm32l1xx_flash_ramfunc.c\r
+ * @author MCD Application Team\r
+ * @version V1.0.0\r
+ * @date 31-December-2010\r
+ * @brief This file provides all the Flash firmware functions which should be\r
+ * executed from the internal SRAM. This file should be placed in \r
+ * internal SRAM. \r
+ * Other FLASH memory functions that can be used from the FLASH are \r
+ * defined in the "stm32l1xx_flash.c" file. \r
+ * @verbatim \r
+ * \r
+ * ARM Compiler\r
+ * ------------\r
+ * RAM functions are defined using the toolchain options. \r
+ * Functions that are be executed in RAM should reside in a separate\r
+ * source module. Using the 'Options for File' dialog you can simply change\r
+ * the 'Code / Const' area of a module to a memory space in physical RAM.\r
+ * Available memory areas are declared in the 'Target' tab of the \r
+ * 'Options for Target' dialog.\r
+ * \r
+ * ICCARM Compiler\r
+ * ---------------\r
+ * RAM functions are defined using a specific toolchain keyword "__ramfunc". \r
+ * \r
+ * GNU Compiler\r
+ * ------------\r
+ * RAM functions are defined using a specific toolchain attribute\r
+ * "__attribute__((section(".data")))".\r
+ * \r
+ * TASKING Compiler\r
+ * ----------------\r
+ * RAM functions are defined using a specific toolchain pragma. This \r
+ * pragma is defined inside this file. \r
+ * \r
+ * @endverbatim \r
+ *\r
+ ******************************************************************************\r
+ * @attention\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>\r
+ ****************************************************************************** \r
+ */ \r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include "stm32l1xx_flash.h"\r
+\r
+/** @addtogroup STM32L1xx_StdPeriph_Driver\r
+ * @{\r
+ */\r
+\r
+/** @defgroup FLASH \r
+ * @brief FLASH driver modules\r
+ * @{\r
+ */ \r
+\r
+/* Private typedef -----------------------------------------------------------*/\r
+/* Private define ------------------------------------------------------------*/\r
+/* Private macro -------------------------------------------------------------*/\r
+/* Private variables ---------------------------------------------------------*/\r
+/* Private function prototypes -----------------------------------------------*/\r
+static __RAM_FUNC GetStatus(void);\r
+static __RAM_FUNC WaitForLastOperation(uint32_t Timeout);\r
+\r
+/* Private functions ---------------------------------------------------------*/\r
+ \r
+/** @defgroup FLASH_Private_Functions\r
+ * @{\r
+ */ \r
+\r
+/** @addtogroup FLASH_Group1\r
+ *\r
+@verbatim \r
+@endverbatim\r
+ * @{\r
+ */ \r
+#if defined ( __TASKING__ )\r
+#pragma section_code_init on\r
+#endif\r
+\r
+/**\r
+ * @brief Enable or disable the power down mode during RUN mode.\r
+ * @note: This function can be used only when the user code is running from Internal SRAM\r
+ * @param NewState: new state of the power down mode during RUN mode.\r
+ * This parameter can be: ENABLE or DISABLE.\r
+ * @retval None\r
+ */\r
+__RAM_FUNC FLASH_RUNPowerDownCmd(FunctionalState NewState)\r
+{\r
+ FLASH_Status status = FLASH_COMPLETE;\r
+ \r
+ if (NewState != DISABLE)\r
+ {\r
+ /* Unlock the RUN_PD bit */\r
+ FLASH->PDKEYR = FLASH_PDKEY1;\r
+ FLASH->PDKEYR = FLASH_PDKEY2;\r
+ \r
+ /* Set the RUN_PD bit in FLASH_ACR register to put Flash in power down mode */\r
+ FLASH->ACR |= (uint32_t)FLASH_ACR_RUN_PD;\r
+\r
+ if((FLASH->ACR & FLASH_ACR_RUN_PD) != FLASH_ACR_RUN_PD)\r
+ {\r
+ status = FLASH_ERROR_PROGRAM;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Clear the RUN_PD bit in FLASH_ACR register to put Flash in idle mode */\r
+ FLASH->ACR &= (uint32_t)(~(uint32_t)FLASH_ACR_RUN_PD);\r
+ }\r
+\r
+ /* Return the Write Status */\r
+ return status; \r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @addtogroup FLASH_Group2\r
+ *\r
+@verbatim \r
+@endverbatim\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Programs a half page in program memory.\r
+ * @param Address: specifies the address to be written.\r
+ * @param pBuffer: pointer to the buffer containing the data to be written to \r
+ * the half page.\r
+ * @note - To correctly run this function, the FLASH_Unlock() function\r
+ * must be called before.\r
+ * - Call the FLASH_Lock() to disable the flash memory access \r
+ * (recommended to protect the FLASH memory against possible unwanted operation)\r
+ * @note Half page write is possible only from SRAM.\r
+ * @note If there are more than 32 words to write, after 32 words another \r
+ * Half Page programming operation starts and has to be finished.\r
+ * @note A half page is written to the program memory only if the first \r
+ * address to load is the start address of a half page (multiple of 128 \r
+ * bytes) and the 31 remaining words to load are in the same half page.\r
+ * @note During the Program memory half page write all read operations are \r
+ * forbidden (this includes DMA read operations and debugger read \r
+ * operations such as breakpoints, periodic updates, etc.)\r
+ * @note If a PGAERR is set during a Program memory half page write, the \r
+ * complete write operation is aborted. Software should then reset the \r
+ * FPRG and PROG/DATA bits and restart the write operation from the \r
+ * beginning. \r
+ * @retval FLASH Status: The returned value can be: \r
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. \r
+ */\r
+__RAM_FUNC FLASH_ProgramHalfPage(uint32_t Address, uint32_t* pBuffer)\r
+{\r
+ uint32_t count = 0; \r
+ \r
+ FLASH_Status status = FLASH_COMPLETE;\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);\r
+ \r
+ if(status == FLASH_COMPLETE)\r
+ {\r
+ /* if the previous operation is completed, proceed to program the new \r
+ half page */\r
+ FLASH->PECR |= FLASH_PECR_FPRG;\r
+ FLASH->PECR |= FLASH_PECR_PROG;\r
+ \r
+ /* Write one half page directly with 32 different words */\r
+ while(count < 32)\r
+ {\r
+ *(__IO uint32_t*) (Address + (4 * count)) = *(pBuffer++);\r
+ count ++; \r
+ }\r
+ /* Wait for last operation to be completed */\r
+ status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);\r
+ \r
+ /* if the write operation is completed, disable the PROG and FPRG bits */\r
+ FLASH->PECR &= (uint32_t)(~FLASH_PECR_PROG);\r
+ FLASH->PECR &= (uint32_t)(~FLASH_PECR_FPRG);\r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @addtogroup FLASH_Group3\r
+ *\r
+@verbatim \r
+@endverbatim\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Erase a double word in data memory.\r
+ * @param Address: specifies the address to be erased\r
+ * @note - To correctly run this function, the DATA_EEPROM_Unlock() function\r
+ * must be called before.\r
+ * - Call the DATA_EEPROM_Lock() to he data EEPROM access\r
+ * and Flash program erase control register access(recommended to protect \r
+ * the DATA_EEPROM against possible unwanted operation) \r
+ * @note Data memory double word erase is possible only from SRAM.\r
+ * @note A double word is erased to the data memory only if the first address \r
+ * to load is the start address of a double word (multiple of 8 bytes) \r
+ * @note During the Data memory double word erase, all read operations are \r
+ * forbidden (this includes DMA read operations and debugger read \r
+ * operations such as breakpoints, periodic updates, etc.) \r
+ * @retval FLASH Status: The returned value can be: \r
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.\r
+ */\r
+\r
+__RAM_FUNC DATA_EEPROM_EraseDoubleWord(uint32_t Address)\r
+{\r
+ FLASH_Status status = FLASH_COMPLETE;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);\r
+ \r
+ if(status == FLASH_COMPLETE)\r
+ {\r
+ /* If the previous operation is completed, proceed to erase the next double word */\r
+ /* Set the ERASE bit */\r
+ FLASH->PECR |= FLASH_PECR_ERASE;\r
+\r
+ /* Set DATA bit */\r
+ FLASH->PECR |= FLASH_PECR_DATA;\r
+ \r
+ /* Write 00000000h to the 2 words to erase */\r
+ *(__IO uint64_t *)Address = 0x00000000;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);\r
+ \r
+ /* If the erase operation is completed, disable the ERASE and DATA bits */\r
+ FLASH->PECR &= (uint32_t)(~FLASH_PECR_ERASE);\r
+ FLASH->PECR &= (uint32_t)(~FLASH_PECR_DATA);\r
+ } \r
+ /* Return the erase status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Write a double word in data memory without erase.\r
+ * @param Address: specifies the address to be written.\r
+ * @param Data: specifies the data to be written.\r
+ * @note - To correctly run this function, the DATA_EEPROM_Unlock() function\r
+ * must be called before.\r
+ * - Call the DATA_EEPROM_Lock() to he data EEPROM access\r
+ * and Flash program erase control register access(recommended to protect \r
+ * the DATA_EEPROM against possible unwanted operation) \r
+ * @note Data memory double word write is possible only from SRAM.\r
+ * @note A data memory double word is written to the data memory only if the \r
+ * first address to load is the start address of a double word (multiple \r
+ * of double word). \r
+ * @note During the Data memory double word write, all read operations are \r
+ * forbidden (this includes DMA read operations and debugger read \r
+ * operations such as breakpoints, periodic updates, etc.) \r
+ * @retval FLASH Status: The returned value can be: \r
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. \r
+ */ \r
+__RAM_FUNC DATA_EEPROM_ProgramDoubleWord(uint32_t Address, uint64_t Data)\r
+{\r
+ FLASH_Status status = FLASH_COMPLETE;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);\r
+ \r
+ if(status == FLASH_COMPLETE)\r
+ {\r
+ /* If the previous operation is completed, proceed to program the new data*/\r
+ FLASH->PECR |= FLASH_PECR_FPRG;\r
+ FLASH->PECR |= FLASH_PECR_DATA;\r
+ \r
+ /* Write the 2 words */ \r
+ *(__IO uint32_t *)Address = (uint32_t) Data;\r
+ Address += 4;\r
+ *(__IO uint32_t *)Address = (uint32_t) (Data >> 32);\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);\r
+ \r
+ /* If the write operation is completed, disable the FPRG and DATA bits */\r
+ FLASH->PECR &= (uint32_t)(~FLASH_PECR_FPRG);\r
+ FLASH->PECR &= (uint32_t)(~FLASH_PECR_DATA); \r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @brief Returns the FLASH Status.\r
+ * @param None\r
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, \r
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP or FLASH_COMPLETE\r
+ */\r
+static __RAM_FUNC GetStatus(void)\r
+{\r
+ FLASH_Status FLASHstatus = FLASH_COMPLETE;\r
+ \r
+ if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) \r
+ {\r
+ FLASHstatus = FLASH_BUSY;\r
+ }\r
+ else \r
+ { \r
+ if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00)\r
+ { \r
+ FLASHstatus = FLASH_ERROR_WRP;\r
+ }\r
+ else \r
+ {\r
+ if((FLASH->SR & (uint32_t)0xFEF0) != (uint32_t)0x00)\r
+ {\r
+ FLASHstatus = FLASH_ERROR_PROGRAM; \r
+ }\r
+ else\r
+ {\r
+ FLASHstatus = FLASH_COMPLETE;\r
+ }\r
+ }\r
+ }\r
+ /* Return the FLASH Status */\r
+ return FLASHstatus;\r
+}\r
+\r
+/**\r
+ * @brief Waits for a FLASH operation to complete or a TIMEOUT to occur.\r
+ * @param Timeout: FLASH programming Timeout\r
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, \r
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
+ * FLASH_TIMEOUT.\r
+ */\r
+static __RAM_FUNC WaitForLastOperation(uint32_t Timeout)\r
+{ \r
+ FLASH_Status status = FLASH_COMPLETE;\r
+ \r
+ /* Check for the FLASH Status */\r
+ status = GetStatus();\r
+ \r
+ /* Wait for a FLASH operation to complete or a TIMEOUT to occur */\r
+ while((status == FLASH_BUSY) && (Timeout != 0x00))\r
+ {\r
+ status = GetStatus();\r
+ Timeout--;\r
+ }\r
+ \r
+ if(Timeout == 0x00 )\r
+ {\r
+ status = FLASH_TIMEOUT;\r
+ }\r
+ /* Return the operation status */\r
+ return status;\r
+}\r
+\r
+#if defined ( __TASKING__ )\r
+#pragma section_code_init restore\r
+#endif\r
+\r
+/**\r
+ * @}\r
+ */\r
+ \r
+ /**\r
+ * @}\r
+ */ \r
+\r
+/**\r
+ * @}\r
+ */ \r
+\r
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/\r