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