]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_SAMV71_Xplained/libchip_samv7/source/efc.c
Update version number ready for V8.2.1 release.
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAMV71_Xplained / libchip_samv7 / source / efc.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License\r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2012, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 /** \addtogroup efc_module Working with EEFC\r
31  * \ingroup peripherals_module\r
32  * The EEFC driver provides the interface to configure and use the EEFC\r
33  * peripheral.\r
34  *\r
35  * The user needs to set the number of wait states depending on the frequency used.\n\r
36  * Configure number of cycles for flash read/write operations in the FWS field of EEFC_FMR.\r
37  *\r
38  * It offers a function to send flash command to EEFC and waits for the\r
39  * flash to be ready.\r
40  *\r
41  * To send flash command, the user could do in either of following way:\r
42  * <ul>\r
43  * <li>Write a correct key, command and argument in EEFC_FCR. </li>\r
44  * <li>Or, Use IAP (In Application Programming) function which is executed from\r
45  * ROM directly, this allows flash programming to be done by code running in flash.</li>\r
46  * <li>Once the command is achieved, it can be detected even by polling EEFC_FSR or interrupt.\r
47  * </ul>\r
48  *\r
49  * The command argument could be a page number,GPNVM number or nothing, it depends on\r
50  * the command itself. Some useful functions in this driver could help user tranlate physical\r
51  * flash address into a page number and vice verse.\r
52  *\r
53  * For more accurate information, please look at the EEFC section of the\r
54  * Datasheet.\r
55  *\r
56  * Related files :\n\r
57  * \ref efc.c\n\r
58  * \ref efc.h.\n\r
59 */\r
60 /*@{*/\r
61 /*@}*/\r
62 \r
63 \r
64 /**\r
65  * \file\r
66  *\r
67  * Implementation of Enhanced Embedded Flash Controller (EEFC).\r
68  *\r
69  */\r
70 \r
71 \r
72 /*----------------------------------------------------------------------------\r
73  *        Headers\r
74  *----------------------------------------------------------------------------*/\r
75 #include "chip.h"\r
76 \r
77 #include <assert.h>\r
78 \r
79 #define EEFC_FCR_FCMD(value) ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))\r
80 \r
81 /*----------------------------------------------------------------------------\r
82  *        Exported functions\r
83  *----------------------------------------------------------------------------*/\r
84 \r
85 extern void EFC_WriteFMR( Efc* efc, uint32_t dwFmr );\r
86 \r
87 #ifdef __ICCARM__\r
88 extern __ramfunc void EFC_WriteFMR( Efc* efc, uint32_t dwFmr )\r
89 #else\r
90 __attribute__ ((section (".ramfunc")))\r
91 extern void EFC_WriteFMR( Efc* efc, uint32_t dwFmr )\r
92 #endif\r
93 {\r
94     efc->EEFC_FMR = dwFmr;\r
95 }\r
96 \r
97 /**\r
98  * \brief Enables the flash ready interrupt source on the EEFC peripheral.\r
99  *\r
100  * \param efc  Pointer to a Efc instance\r
101  */\r
102 extern void EFC_EnableFrdyIt( Efc* efc )\r
103 {\r
104     uint32_t dwFmr;\r
105 \r
106     dwFmr = efc->EEFC_FMR |= EEFC_FMR_FRDY;\r
107     EFC_WriteFMR(efc, dwFmr);\r
108 }\r
109 \r
110 /**\r
111  * \brief Disables the flash ready interrupt source on the EEFC peripheral.\r
112  *\r
113  * \param efc  Pointer to a Efc instance\r
114  */\r
115 extern void EFC_DisableFrdyIt( Efc* efc )\r
116 {\r
117     uint32_t dwFmr;\r
118 \r
119     dwFmr = efc->EEFC_FMR & (~EEFC_FMR_FRDY);\r
120     EFC_WriteFMR(efc, dwFmr);\r
121 }\r
122 \r
123 \r
124 /**\r
125  * \brief Set read/write wait state on the EEFC perpherial.\r
126  *\r
127  * \param efc  Pointer to a Efc instance\r
128  * \param cycles  the number of wait states in cycle.\r
129  */\r
130 extern void EFC_SetWaitState( Efc* efc, uint8_t ucCycles )\r
131 {\r
132     uint32_t dwFmr ;\r
133 \r
134     dwFmr = efc->EEFC_FMR ;\r
135     dwFmr &= ~((uint32_t)EEFC_FMR_FWS_Msk) ;\r
136     dwFmr |= EEFC_FMR_FWS(ucCycles);\r
137     EFC_WriteFMR(efc, dwFmr);\r
138 }\r
139 \r
140 /**\r
141  * \brief Returns the current status of the EEFC.\r
142  *\r
143  * \note Keep in mind that this function clears the value of some status bits (LOCKE, PROGE).\r
144  *\r
145  * \param efc  Pointer to a Efc instance\r
146  */\r
147 extern uint32_t EFC_GetStatus( Efc* efc )\r
148 {\r
149     return efc->EEFC_FSR ;\r
150 }\r
151 \r
152 /**\r
153  * \brief Returns the result of the last executed command.\r
154  *\r
155  * \param efc  Pointer to a Efc instance\r
156  */\r
157 extern uint32_t EFC_GetResult( Efc* efc )\r
158 {\r
159     return efc->EEFC_FRR ;\r
160 }\r
161 \r
162 /**\r
163  * \brief Translates the given address page and offset values.\r
164  * \note The resulting values are stored in the provided variables if they are not null.\r
165  *\r
166  * \param efc  Pointer to a Efc instance\r
167  * \param address  Address to translate.\r
168  * \param pPage  First page accessed.\r
169  * \param pOffset  Byte offset in first page.\r
170  */\r
171 extern void EFC_TranslateAddress( Efc** ppEfc, uint32_t dwAddress, uint16_t* pwPage, uint16_t* pwOffset )\r
172 {\r
173     assert( dwAddress >= IFLASH_ADDR ) ;\r
174     assert( dwAddress <= (IFLASH_ADDR + IFLASH_SIZE) ) ;\r
175 \r
176     /* Store values */\r
177     if ( ppEfc )\r
178     {\r
179         *ppEfc = EFC ;\r
180     }\r
181 \r
182     if ( pwPage )\r
183     {\r
184         *pwPage = (dwAddress - IFLASH_ADDR) / IFLASH_PAGE_SIZE ;\r
185     }\r
186 \r
187     if ( pwOffset )\r
188     {\r
189         *pwOffset = (dwAddress - IFLASH_ADDR) % IFLASH_PAGE_SIZE; ;\r
190     }\r
191 }\r
192    \r
193 \r
194 /**\r
195  * \brief Computes the address of a flash access given the page and offset.\r
196  *\r
197  * \param efc  Pointer to a Efc instance\r
198  * \param page  Page number.\r
199  * \param offset  Byte offset inside page.\r
200  * \param pAddress  Computed address (optional).\r
201  */\r
202 extern void EFC_ComputeAddress( Efc *efc, uint16_t wPage, uint16_t wOffset, uint32_t *pdwAddress )\r
203 {\r
204     uint32_t dwAddress ;\r
205 \r
206     /* Stop warning */\r
207     efc = efc;\r
208 \r
209     assert( efc ) ;\r
210     assert( wPage <= IFLASH_NB_OF_PAGES ) ;\r
211     assert( wOffset < IFLASH_PAGE_SIZE ) ;\r
212     dwAddress = IFLASH_ADDR + wPage * IFLASH_PAGE_SIZE + wOffset ;\r
213 \r
214     /* Store result */\r
215     if ( pdwAddress != NULL )\r
216     {\r
217         *pdwAddress = dwAddress ;\r
218     }\r
219 }\r
220 \r
221 \r
222 \r
223 /**\r
224  * \brief Performs the given command and wait until its completion (or an error).\r
225  *\r
226  * \param efc  Pointer to a Efc instance\r
227  * \param command  Command to perform.\r
228  * \param argument  Optional command argument.\r
229  *\r
230  * \return 0 if successful, otherwise returns an error code.\r
231  */\r
232 \r
233 extern uint32_t EFC_PerformCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument, uint32_t dwUseIAP )\r
234 {\r
235     if ( dwUseIAP != 0 )\r
236     {\r
237         /* Pointer on IAP function in ROM */\r
238         static uint32_t (*IAP_PerformCommand)( uint32_t, uint32_t ) ;\r
239 \r
240         IAP_PerformCommand = (uint32_t (*)( uint32_t, uint32_t )) *((uint32_t*)CHIP_FLASH_IAP_ADDRESS ) ;\r
241         if (efc == EFC) {\r
242             IAP_PerformCommand( 0, EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ) ;\r
243         }\r
244         return (efc->EEFC_FSR & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR)) ;\r
245     }\r
246     else\r
247     {\r
248         uint32_t dwStatus ;\r
249 \r
250         efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ;\r
251         do\r
252         {\r
253             dwStatus = efc->EEFC_FSR ;\r
254         }\r
255         while ( (dwStatus & EEFC_FSR_FRDY) != EEFC_FSR_FRDY ) ;\r
256 \r
257         return ( dwStatus & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR) ) ;\r
258     }\r
259 }\r
260 \r
261 /**\r
262  * \brief Set flash access mode.\r
263  *\r
264  * \param dwMode - 0:128-bit, (1<<24):64-bit\r
265  */\r
266 extern void EFC_SetFlashAccessMode(Efc* efc, uint32_t dwMode)\r
267 {\r
268     uint32_t dwFmr;\r
269 \r
270     dwFmr = (efc->EEFC_FMR & (~EEFC_FMR_FAM)) | dwMode;\r
271     EFC_WriteFMR(efc, dwFmr);\r
272 }\r
273 \r