1 /**
2 * @file flc_me10.c
3 * @brief Flash Controler driver.
4 * @details This driver can be used to operate on the embedded flash memory.
5 */
6 /******************************************************************************
7 *
8 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9 * Analog Devices, Inc.),
10 * Copyright (C) 2023-2024 Analog Devices, Inc.
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 ******************************************************************************/
25
26 /* **** Includes **** */
27 #include <string.h>
28 #include "mxc_errors.h"
29 #include "mxc_sys.h"
30 #include "flc.h"
31 #include "flc_reva.h"
32 #include "flc_common.h"
33 #include "icc.h"
34
35 /* **** Definitions **** */
36
37 /* **** Globals **** */
38
39 /* **** Functions **** */
40
41 //******************************************************************************
MXC_FLC_ME10_Flash_Operation(void)42 void MXC_FLC_ME10_Flash_Operation(void)
43 {
44 /* Flush all instruction caches */
45 MXC_ICC_Flush();
46 }
47
48 //******************************************************************************
MXC_FLC_ME10_GetByAddress(mxc_flc_regs_t ** flc,uint32_t addr)49 int MXC_FLC_ME10_GetByAddress(mxc_flc_regs_t **flc, uint32_t addr)
50 {
51 if ((addr >= MXC_FLASH_MEM_BASE) && (addr < (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE))) {
52 *flc = MXC_FLC;
53 } else if ((addr >= MXC_INFO_MEM_BASE) && (addr < (MXC_INFO_MEM_BASE + MXC_INFO_MEM_SIZE))) {
54 *flc = MXC_FLC;
55 } else {
56 return E_BAD_PARAM;
57 }
58
59 return E_NO_ERROR;
60 }
61
62 //******************************************************************************
MXC_FLC_ME10_GetPhysicalAddress(uint32_t addr,uint32_t * result)63 int MXC_FLC_ME10_GetPhysicalAddress(uint32_t addr, uint32_t *result)
64 {
65 if ((addr >= MXC_FLASH_MEM_BASE) && (addr < (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE))) {
66 *result = (addr & (MXC_FLASH_MEM_SIZE - 1));
67 } else if ((addr >= MXC_INFO_MEM_BASE) && (addr < (MXC_INFO_MEM_BASE + MXC_INFO_MEM_SIZE))) {
68 *result = (addr & (MXC_INFO_MEM_SIZE - 1)) + (MXC_INFO_MEM_BASE - MXC_FLASH_MEM_BASE);
69 } else {
70 return E_BAD_PARAM;
71 }
72
73 return E_NO_ERROR;
74 }
75
76 // *****************************************************************************
MXC_FLC_Init(void)77 int MXC_FLC_Init(void)
78 {
79 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_FLC);
80 return E_NO_ERROR;
81 }
82
83 // *****************************************************************************
84 #if IAR_PRAGMAS
85 #pragma section = ".flashprog"
86 #else
87 __attribute__((section(".flashprog")))
88 #endif
MXC_FLC_Busy(void)89 int MXC_FLC_Busy(void)
90 {
91 return MXC_FLC_RevA_Busy();
92 }
93
94 // *****************************************************************************
MXC_FLC_MassErase(void)95 int MXC_FLC_MassErase(void)
96 {
97 int err;
98
99 if ((err = MXC_FLC_RevA_MassErase((mxc_flc_reva_regs_t *)MXC_FLC)) != E_NO_ERROR) {
100 return err;
101 }
102
103 MXC_FLC_ME10_Flash_Operation();
104
105 return E_NO_ERROR;
106 }
107
108 // *****************************************************************************
109 #if IAR_PRAGMAS
110 #pragma section = ".flashprog"
111 #else
112 __attribute__((section(".flashprog")))
113 #endif
MXC_FLC_PageErase(uint32_t address)114 int MXC_FLC_PageErase(uint32_t address)
115 {
116 int err;
117 uint32_t physicalAddress;
118
119 if ((err = MXC_FLC_ME10_GetPhysicalAddress(address, &physicalAddress)) != E_NO_ERROR) {
120 return err;
121 }
122
123 if ((err = MXC_FLC_RevA_PageErase((mxc_flc_reva_regs_t *)MXC_FLC, physicalAddress)) !=
124 E_NO_ERROR) {
125 return err;
126 }
127
128 MXC_FLC_ME10_Flash_Operation();
129
130 return E_NO_ERROR;
131 }
132
133 // *****************************************************************************
MXC_FLC_Read(int address,void * buffer,int len)134 void MXC_FLC_Read(int address, void *buffer, int len)
135 {
136 if (address < MXC_FLASH_MEM_BASE || address >= (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE)) {
137 return;
138 }
139 MXC_FLC_Com_Read(address, buffer, len);
140 }
141
142 // *****************************************************************************
MXC_FLC_Write(uint32_t address,uint32_t length,uint32_t * buffer)143 int MXC_FLC_Write(uint32_t address, uint32_t length, uint32_t *buffer)
144 {
145 return MXC_FLC_Com_Write(address, length, buffer);
146 }
147
148 // *****************************************************************************
MXC_FLC_Write32(uint32_t address,uint32_t data)149 int MXC_FLC_Write32(uint32_t address, uint32_t data)
150 {
151 int err;
152 uint32_t physicalAddress, aligned;
153
154 aligned = address & ~0xf;
155 if ((err = MXC_FLC_ME10_GetPhysicalAddress(aligned, &physicalAddress)) != E_NO_ERROR) {
156 return err;
157 }
158
159 err = MXC_FLC_RevA_Write32((mxc_flc_reva_regs_t *)MXC_FLC, address, data, physicalAddress);
160
161 MXC_FLC_ME10_Flash_Operation();
162
163 return err;
164 }
165
166 // *****************************************************************************
167 #if IAR_PRAGMAS
168 #pragma section = ".flashprog"
169 #else
170 __attribute__((section(".flashprog")))
171 #endif
MXC_FLC_Write128(uint32_t address,uint32_t * data)172 int MXC_FLC_Write128(uint32_t address, uint32_t *data)
173 {
174 int err;
175 uint32_t physicalAddress, aligned;
176
177 aligned = address & ~0xf;
178 if ((err = MXC_FLC_ME10_GetPhysicalAddress(aligned, &physicalAddress)) != E_NO_ERROR) {
179 return err;
180 }
181
182 if ((err = MXC_FLC_RevA_Write128((mxc_flc_reva_regs_t *)MXC_FLC, physicalAddress, data)) !=
183 E_NO_ERROR) {
184 return err;
185 }
186
187 MXC_FLC_ME10_Flash_Operation();
188
189 return MXC_FLC_Com_VerifyData(address, 4, data);
190 }
191
192 // *****************************************************************************
MXC_FLC_EnableInt(uint32_t mask)193 int MXC_FLC_EnableInt(uint32_t mask)
194 {
195 return MXC_FLC_RevA_EnableInt(mask);
196 }
197
198 // *****************************************************************************
MXC_FLC_DisableInt(uint32_t mask)199 int MXC_FLC_DisableInt(uint32_t mask)
200 {
201 return MXC_FLC_RevA_DisableInt(mask);
202 }
203
204 // *****************************************************************************
MXC_FLC_GetFlags(void)205 int MXC_FLC_GetFlags(void)
206 {
207 return MXC_FLC_RevA_GetFlags();
208 }
209
210 // *****************************************************************************
MXC_FLC_ClearFlags(uint32_t mask)211 int MXC_FLC_ClearFlags(uint32_t mask)
212 {
213 return MXC_FLC_RevA_ClearFlags(mask);
214 }
215
216 // *****************************************************************************
MXC_FLC_UnlockInfoBlock(uint32_t address)217 int MXC_FLC_UnlockInfoBlock(uint32_t address)
218 {
219 return MXC_FLC_RevA_UnlockInfoBlock((mxc_flc_reva_regs_t *)MXC_FLC, address);
220 }
221
222 // *****************************************************************************
MXC_FLC_LockInfoBlock(uint32_t address)223 int MXC_FLC_LockInfoBlock(uint32_t address)
224 {
225 return MXC_FLC_RevA_LockInfoBlock((mxc_flc_reva_regs_t *)MXC_FLC, address);
226 }
227
228 //******************************************************************************
MXC_FLC_BlockPageWrite(uint32_t address)229 int MXC_FLC_BlockPageWrite(uint32_t address)
230 {
231 /* MAX32650 does not support flash page read and write locks */
232 return E_NOT_SUPPORTED;
233 }
234
235 //******************************************************************************
MXC_FLC_BlockPageRead(uint32_t address)236 int MXC_FLC_BlockPageRead(uint32_t address)
237 {
238 /* MAX32650 does not support flash page read and write locks */
239 return E_NOT_SUPPORTED;
240 }
241
242 //******************************************************************************
MXC_FLC_GetWELR(uint32_t address,uint32_t page_num)243 volatile uint32_t *MXC_FLC_GetWELR(uint32_t address, uint32_t page_num)
244 {
245 /* MAX32650 does not support flash page read and write locks */
246 return NULL;
247 }
248
249 //******************************************************************************
MXC_FLC_GetRLR(uint32_t address,uint32_t page_num)250 volatile uint32_t *MXC_FLC_GetRLR(uint32_t address, uint32_t page_num)
251 {
252 /* MAX32650 does not support flash page read and write locks */
253 return NULL;
254 }
255