1 /**
2 *********************************************************************************
3 *
4 * @file ald_flash.c
5 * @brief FLASH module driver.
6 *
7 * @version V1.0
8 * @date 17 Jun 2019
9 * @author AE Team
10 * @note
11 * Change Logs:
12 * Date Author Notes
13 * 17 Jun 2019 AE Team The first version
14 *
15 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 *
19 * Licensed under the Apache License, Version 2.0 (the License); you may
20 * not use this file except in compliance with the License.
21 * You may obtain a copy of the License at
22 *
23 * www.apache.org/licenses/LICENSE-2.0
24 *
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
27 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
30 **********************************************************************************
31 * @verbatim
32 ==============================================================================
33 ##### FLASH Peripheral features #####
34 ==============================================================================
35 [..]
36 Base address is 0x00000000
37
38 [..]
39 FLASH have just one programme mode , word programme.
40 word programme can programme 8 bytes once ;
41
42 ==============================================================================
43 ##### How to use this driver #####
44 ==============================================================================
45 [..]
46 This driver provide private functions for ald_flash_ext.c to use
47 @endverbatim
48 */
49
50 #include "ald_conf.h"
51
52
53 /** @addtogroup ES32FXXX_ALD
54 * @{
55 */
56
57 /** @defgroup FLASH FLASH
58 * @brief FLASH module driver
59 * @{
60 */
61
62 #ifdef ALD_FLASH
63
64 #if defined ( __ICCARM__ )
65 #define __RAMFUNC __ramfunc
66 #else
67 #define __RAMFUNC
68 #endif
69
70 /** @defgroup Flash_Private_Variables Flash Private Variables
71 * @{
72 */
73 /* global variable*/
74 static op_cmd_type OP_CMD = OP_FLASH;
75 /**
76 * @}
77 */
78
79 /** @defgroup Flash_Private_Functions Flash Private Functions
80 * @brief Flash Private functions
81 * @{
82 */
83 /**
84 * @brief Unlock the flash.
85 * @retval Status, see @ref ald_status_t.
86 */
flash_unlock(void)87 __RAMFUNC static ald_status_t flash_unlock(void)
88 {
89 uint16_t i;
90 uint16_t op_cmd = OP_CMD;
91
92 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK))
93 return ERROR;
94
95 FLASH_REG_UNLOCK();
96 FLASH_IAP_ENABLE();
97 FLASH_REQ();
98
99 for (i = 0; i < 0xFFFF; i++) {
100 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK))
101 break;
102 }
103
104 return i == 0xFFFF ? ERROR : OK;
105 }
106
107 /**
108 * @brief Lock the flash.
109 * @retval Status, see @ref ald_status_t.
110 */
flash_lock(void)111 __RAMFUNC static ald_status_t flash_lock(void)
112 {
113 uint16_t i;
114 uint16_t op_cmd = OP_CMD;
115
116 FLASH_REG_UNLOCK();
117 WRITE_REG(MSC->FLASHCR, 0x0);
118
119 for (i = 0; i < 0xFFFF; i++) {
120 if (!(READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK)))
121 break;
122 }
123
124 return i == 0xFFFF ? ERROR : OK;
125 }
126
127 /**
128 * @brief Erase one page.
129 * @param addr: The erased page's address
130 * @retval Status, see @ref ald_status_t.
131 */
flash_page_erase(uint32_t addr)132 __RAMFUNC ald_status_t flash_page_erase(uint32_t addr)
133 {
134 uint32_t i;
135 uint16_t op_cmd = OP_CMD;
136
137 if (flash_unlock() != OK)
138 goto end;
139
140 if (op_cmd == OP_FLASH) {
141 CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);
142 MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, FLASH_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS);
143 }
144 else {
145 SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);
146 MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, INFO_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS);
147 }
148
149 WRITE_REG(MSC->FLASHCMD, FLASH_CMD_PE);
150
151 for (i = 0; i < 0xFFFF; i++) {
152 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK))
153 continue;
154 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_ADDR_OV_MSK))
155 goto end;
156 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_WRP_FLAG_MSK))
157 goto end;
158 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_SERA_MSK))
159 break;
160 }
161
162 if (i == 0xFFFF)
163 goto end;
164
165 if (flash_lock() == ERROR)
166 goto end;
167
168 return OK;
169 end:
170 flash_lock();
171 return ERROR;
172 }
173
174 /**
175 * @brief Programme a word.
176 * @param addr: The word's address, it is must word align.
177 * @param data: The 8 bytes data be write.
178 * @param len: The number of data be write.
179 * @param fifo: Choose if use fifo.
180 * @retval Status, see @ref ald_status_t.
181 */
flash_word_program(uint32_t addr,uint32_t * data,uint32_t len,uint32_t fifo)182 __RAMFUNC ald_status_t flash_word_program(uint32_t addr, uint32_t *data, uint32_t len, uint32_t fifo)
183 {
184 uint16_t i = 0;
185 uint16_t prog_len;
186 uint32_t *p_data = data;
187 uint16_t op_cmd = OP_CMD;
188
189 if (flash_unlock() != OK)
190 goto end;
191
192 if (op_cmd == OP_FLASH)
193 CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);
194 else
195 SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);
196
197 MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, addr << MSC_FLASHADDR_ADDR_POSS);
198 MODIFY_REG(MSC->FLASHCR, MSC_FLASHCR_FIFOEN_MSK, fifo << MSC_FLASHCR_FIFOEN_POS);
199
200 for (prog_len = 0; prog_len < len; prog_len++) {
201 if (fifo) {
202 WRITE_REG(MSC->FLASHFIFO, p_data[0]);
203 WRITE_REG(MSC->FLASHFIFO, p_data[1]);
204 }
205 else {
206 WRITE_REG(MSC->FLASHDL, p_data[0]);
207 WRITE_REG(MSC->FLASHDH, p_data[1]);
208 WRITE_REG(MSC->FLASHCMD, FLASH_CMD_WP);
209 }
210
211 p_data += 2;
212
213 for (i = 0; i < 0xFFFF; i++) {
214 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK))
215 continue;
216 if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_PROG_MSK))
217 break;
218 }
219 }
220 if (i == 0xFFFF)
221 goto end;
222
223 if (flash_lock() == ERROR)
224 goto end;
225
226 return OK;
227 end:
228 flash_lock();
229 return ERROR;
230 }
231 /**
232 * @}
233 */
234
235 #endif
236
237 /**
238 * @}
239 */
240
241 /**
242 * @}
243 */
244