1*5fd0122aSMatthias Ringwald /* --COPYRIGHT--,BSD
2*5fd0122aSMatthias Ringwald * Copyright (c) 2017, Texas Instruments Incorporated
3*5fd0122aSMatthias Ringwald * All rights reserved.
4*5fd0122aSMatthias Ringwald *
5*5fd0122aSMatthias Ringwald * Redistribution and use in source and binary forms, with or without
6*5fd0122aSMatthias Ringwald * modification, are permitted provided that the following conditions
7*5fd0122aSMatthias Ringwald * are met:
8*5fd0122aSMatthias Ringwald *
9*5fd0122aSMatthias Ringwald * * Redistributions of source code must retain the above copyright
10*5fd0122aSMatthias Ringwald * notice, this list of conditions and the following disclaimer.
11*5fd0122aSMatthias Ringwald *
12*5fd0122aSMatthias Ringwald * * Redistributions in binary form must reproduce the above copyright
13*5fd0122aSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the
14*5fd0122aSMatthias Ringwald * documentation and/or other materials provided with the distribution.
15*5fd0122aSMatthias Ringwald *
16*5fd0122aSMatthias Ringwald * * Neither the name of Texas Instruments Incorporated nor the names of
17*5fd0122aSMatthias Ringwald * its contributors may be used to endorse or promote products derived
18*5fd0122aSMatthias Ringwald * from this software without specific prior written permission.
19*5fd0122aSMatthias Ringwald *
20*5fd0122aSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21*5fd0122aSMatthias Ringwald * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22*5fd0122aSMatthias Ringwald * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23*5fd0122aSMatthias Ringwald * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24*5fd0122aSMatthias Ringwald * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25*5fd0122aSMatthias Ringwald * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26*5fd0122aSMatthias Ringwald * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27*5fd0122aSMatthias Ringwald * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28*5fd0122aSMatthias Ringwald * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29*5fd0122aSMatthias Ringwald * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30*5fd0122aSMatthias Ringwald * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*5fd0122aSMatthias Ringwald * --/COPYRIGHT--*/
32*5fd0122aSMatthias Ringwald /* Standard Includes */
33*5fd0122aSMatthias Ringwald #include <stdint.h>
34*5fd0122aSMatthias Ringwald
35*5fd0122aSMatthias Ringwald /* DriverLib Includes */
36*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/flash.h>
37*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/sysctl.h>
38*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
39*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/cpu.h>
40*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/debug.h>
41*5fd0122aSMatthias Ringwald
42*5fd0122aSMatthias Ringwald /* Define to ensure that our current MSP432 has the FLCTL module. This
43*5fd0122aSMatthias Ringwald definition is included in the device specific header file */
44*5fd0122aSMatthias Ringwald #ifdef __MCU_HAS_FLCTL__
45*5fd0122aSMatthias Ringwald
46*5fd0122aSMatthias Ringwald static const uint32_t MAX_ERASE_NO_TLV = 50;
47*5fd0122aSMatthias Ringwald static const uint32_t MAX_PROGRAM_NO_TLV = 5;
48*5fd0122aSMatthias Ringwald
49*5fd0122aSMatthias Ringwald static volatile uint32_t* __getBurstProgramRegs[16] =
50*5fd0122aSMatthias Ringwald { &FLCTL->PRGBRST_DATA0_0, &FLCTL->PRGBRST_DATA0_1,
51*5fd0122aSMatthias Ringwald &FLCTL->PRGBRST_DATA0_2, &FLCTL->PRGBRST_DATA0_3,
52*5fd0122aSMatthias Ringwald &FLCTL->PRGBRST_DATA1_0, &FLCTL->PRGBRST_DATA1_1,
53*5fd0122aSMatthias Ringwald &FLCTL->PRGBRST_DATA1_2, &FLCTL->PRGBRST_DATA1_3,
54*5fd0122aSMatthias Ringwald &FLCTL->PRGBRST_DATA2_0, &FLCTL->PRGBRST_DATA2_1,
55*5fd0122aSMatthias Ringwald &FLCTL->PRGBRST_DATA2_2, &FLCTL->PRGBRST_DATA2_3,
56*5fd0122aSMatthias Ringwald &FLCTL->PRGBRST_DATA3_0, &FLCTL->PRGBRST_DATA3_1,
57*5fd0122aSMatthias Ringwald &FLCTL->PRGBRST_DATA3_2, &FLCTL->PRGBRST_DATA3_3 };
58*5fd0122aSMatthias Ringwald
getUserFlashSector(uint32_t addr)59*5fd0122aSMatthias Ringwald static uint32_t getUserFlashSector(uint32_t addr)
60*5fd0122aSMatthias Ringwald {
61*5fd0122aSMatthias Ringwald if (addr > 0x1ffff)
62*5fd0122aSMatthias Ringwald {
63*5fd0122aSMatthias Ringwald addr = addr - 0x20000;
64*5fd0122aSMatthias Ringwald }
65*5fd0122aSMatthias Ringwald
66*5fd0122aSMatthias Ringwald switch (addr)
67*5fd0122aSMatthias Ringwald {
68*5fd0122aSMatthias Ringwald case 0:
69*5fd0122aSMatthias Ringwald return FLASH_SECTOR0;
70*5fd0122aSMatthias Ringwald case 0x1000:
71*5fd0122aSMatthias Ringwald return FLASH_SECTOR1;
72*5fd0122aSMatthias Ringwald case 0x2000:
73*5fd0122aSMatthias Ringwald return FLASH_SECTOR2;
74*5fd0122aSMatthias Ringwald case 0x3000:
75*5fd0122aSMatthias Ringwald return FLASH_SECTOR3;
76*5fd0122aSMatthias Ringwald case 0x4000:
77*5fd0122aSMatthias Ringwald return FLASH_SECTOR4;
78*5fd0122aSMatthias Ringwald case 0x5000:
79*5fd0122aSMatthias Ringwald return FLASH_SECTOR5;
80*5fd0122aSMatthias Ringwald case 0x6000:
81*5fd0122aSMatthias Ringwald return FLASH_SECTOR6;
82*5fd0122aSMatthias Ringwald case 0x7000:
83*5fd0122aSMatthias Ringwald return FLASH_SECTOR7;
84*5fd0122aSMatthias Ringwald case 0x8000:
85*5fd0122aSMatthias Ringwald return FLASH_SECTOR8;
86*5fd0122aSMatthias Ringwald case 0x9000:
87*5fd0122aSMatthias Ringwald return FLASH_SECTOR9;
88*5fd0122aSMatthias Ringwald case 0xA000:
89*5fd0122aSMatthias Ringwald return FLASH_SECTOR10;
90*5fd0122aSMatthias Ringwald case 0xB000:
91*5fd0122aSMatthias Ringwald return FLASH_SECTOR11;
92*5fd0122aSMatthias Ringwald case 0xC000:
93*5fd0122aSMatthias Ringwald return FLASH_SECTOR12;
94*5fd0122aSMatthias Ringwald case 0xD000:
95*5fd0122aSMatthias Ringwald return FLASH_SECTOR13;
96*5fd0122aSMatthias Ringwald case 0xE000:
97*5fd0122aSMatthias Ringwald return FLASH_SECTOR14;
98*5fd0122aSMatthias Ringwald case 0xF000:
99*5fd0122aSMatthias Ringwald return FLASH_SECTOR15;
100*5fd0122aSMatthias Ringwald case 0x10000:
101*5fd0122aSMatthias Ringwald return FLASH_SECTOR16;
102*5fd0122aSMatthias Ringwald case 0x11000:
103*5fd0122aSMatthias Ringwald return FLASH_SECTOR17;
104*5fd0122aSMatthias Ringwald case 0x12000:
105*5fd0122aSMatthias Ringwald return FLASH_SECTOR18;
106*5fd0122aSMatthias Ringwald case 0x13000:
107*5fd0122aSMatthias Ringwald return FLASH_SECTOR19;
108*5fd0122aSMatthias Ringwald case 0x14000:
109*5fd0122aSMatthias Ringwald return FLASH_SECTOR20;
110*5fd0122aSMatthias Ringwald case 0x15000:
111*5fd0122aSMatthias Ringwald return FLASH_SECTOR21;
112*5fd0122aSMatthias Ringwald case 0x16000:
113*5fd0122aSMatthias Ringwald return FLASH_SECTOR22;
114*5fd0122aSMatthias Ringwald case 0x17000:
115*5fd0122aSMatthias Ringwald return FLASH_SECTOR23;
116*5fd0122aSMatthias Ringwald case 0x18000:
117*5fd0122aSMatthias Ringwald return FLASH_SECTOR24;
118*5fd0122aSMatthias Ringwald case 0x19000:
119*5fd0122aSMatthias Ringwald return FLASH_SECTOR25;
120*5fd0122aSMatthias Ringwald case 0x1A000:
121*5fd0122aSMatthias Ringwald return FLASH_SECTOR26;
122*5fd0122aSMatthias Ringwald case 0x1B000:
123*5fd0122aSMatthias Ringwald return FLASH_SECTOR27;
124*5fd0122aSMatthias Ringwald case 0x1C000:
125*5fd0122aSMatthias Ringwald return FLASH_SECTOR28;
126*5fd0122aSMatthias Ringwald case 0x1D000:
127*5fd0122aSMatthias Ringwald return FLASH_SECTOR29;
128*5fd0122aSMatthias Ringwald case 0x1E000:
129*5fd0122aSMatthias Ringwald return FLASH_SECTOR30;
130*5fd0122aSMatthias Ringwald case 0x1F000:
131*5fd0122aSMatthias Ringwald return FLASH_SECTOR31;
132*5fd0122aSMatthias Ringwald default:
133*5fd0122aSMatthias Ringwald ASSERT(false);
134*5fd0122aSMatthias Ringwald return 0;
135*5fd0122aSMatthias Ringwald }
136*5fd0122aSMatthias Ringwald }
137*5fd0122aSMatthias Ringwald
FlashCtl_getMemoryInfo(uint32_t addr,uint32_t * bankNum,uint32_t * sectorNum)138*5fd0122aSMatthias Ringwald void FlashCtl_getMemoryInfo(uint32_t addr, uint32_t *bankNum,
139*5fd0122aSMatthias Ringwald uint32_t *sectorNum)
140*5fd0122aSMatthias Ringwald {
141*5fd0122aSMatthias Ringwald uint32_t bankLimit;
142*5fd0122aSMatthias Ringwald
143*5fd0122aSMatthias Ringwald bankLimit = SysCtl_getFlashSize() / 2;
144*5fd0122aSMatthias Ringwald
145*5fd0122aSMatthias Ringwald if (addr > bankLimit)
146*5fd0122aSMatthias Ringwald {
147*5fd0122aSMatthias Ringwald *(bankNum) = FLASH_BANK1;
148*5fd0122aSMatthias Ringwald addr = (addr - bankLimit);
149*5fd0122aSMatthias Ringwald } else
150*5fd0122aSMatthias Ringwald {
151*5fd0122aSMatthias Ringwald *(bankNum) = FLASH_BANK0;
152*5fd0122aSMatthias Ringwald }
153*5fd0122aSMatthias Ringwald
154*5fd0122aSMatthias Ringwald *(sectorNum) = (addr) / 4096;
155*5fd0122aSMatthias Ringwald }
156*5fd0122aSMatthias Ringwald
_FlashCtl_Program8(uint32_t src,uint32_t dest,uint32_t mTries)157*5fd0122aSMatthias Ringwald static bool _FlashCtl_Program8(uint32_t src, uint32_t dest, uint32_t mTries)
158*5fd0122aSMatthias Ringwald {
159*5fd0122aSMatthias Ringwald uint32_t ii;
160*5fd0122aSMatthias Ringwald uint8_t data;
161*5fd0122aSMatthias Ringwald
162*5fd0122aSMatthias Ringwald /* Enabling the correct verification settings */
163*5fd0122aSMatthias Ringwald FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
164*5fd0122aSMatthias Ringwald FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
165*5fd0122aSMatthias Ringwald
166*5fd0122aSMatthias Ringwald data = HWREG8(src);
167*5fd0122aSMatthias Ringwald
168*5fd0122aSMatthias Ringwald for (ii = 0; ii < mTries; ii++)
169*5fd0122aSMatthias Ringwald {
170*5fd0122aSMatthias Ringwald /* Clearing flags */
171*5fd0122aSMatthias Ringwald FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED
172*5fd0122aSMatthias Ringwald | FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE);
173*5fd0122aSMatthias Ringwald
174*5fd0122aSMatthias Ringwald HWREG8(dest) = data;
175*5fd0122aSMatthias Ringwald
176*5fd0122aSMatthias Ringwald while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE))
177*5fd0122aSMatthias Ringwald {
178*5fd0122aSMatthias Ringwald __no_operation();
179*5fd0122aSMatthias Ringwald }
180*5fd0122aSMatthias Ringwald
181*5fd0122aSMatthias Ringwald /* Pre-Verify */
182*5fd0122aSMatthias Ringwald if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS)
183*5fd0122aSMatthias Ringwald && BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS)))
184*5fd0122aSMatthias Ringwald {
185*5fd0122aSMatthias Ringwald data = __FlashCtl_remaskData8Pre(data, dest);
186*5fd0122aSMatthias Ringwald
187*5fd0122aSMatthias Ringwald if (data != 0xFF)
188*5fd0122aSMatthias Ringwald {
189*5fd0122aSMatthias Ringwald FlashCtl_clearProgramVerification(FLASH_REGPRE);
190*5fd0122aSMatthias Ringwald continue;
191*5fd0122aSMatthias Ringwald }
192*5fd0122aSMatthias Ringwald
193*5fd0122aSMatthias Ringwald }
194*5fd0122aSMatthias Ringwald
195*5fd0122aSMatthias Ringwald /* Post Verify */
196*5fd0122aSMatthias Ringwald if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS)))
197*5fd0122aSMatthias Ringwald {
198*5fd0122aSMatthias Ringwald data = __FlashCtl_remaskData8Post(data, dest);
199*5fd0122aSMatthias Ringwald
200*5fd0122aSMatthias Ringwald /* Seeing if we actually need to do another pulse */
201*5fd0122aSMatthias Ringwald if (data == 0xFF)
202*5fd0122aSMatthias Ringwald return true;
203*5fd0122aSMatthias Ringwald
204*5fd0122aSMatthias Ringwald FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
205*5fd0122aSMatthias Ringwald continue;
206*5fd0122aSMatthias Ringwald }
207*5fd0122aSMatthias Ringwald
208*5fd0122aSMatthias Ringwald /* If we got this far, return true */
209*5fd0122aSMatthias Ringwald return true;
210*5fd0122aSMatthias Ringwald
211*5fd0122aSMatthias Ringwald }
212*5fd0122aSMatthias Ringwald
213*5fd0122aSMatthias Ringwald return false;
214*5fd0122aSMatthias Ringwald
215*5fd0122aSMatthias Ringwald }
216*5fd0122aSMatthias Ringwald
_FlashCtl_Program32(uint32_t src,uint32_t dest,uint32_t mTries)217*5fd0122aSMatthias Ringwald static bool _FlashCtl_Program32(uint32_t src, uint32_t dest, uint32_t mTries)
218*5fd0122aSMatthias Ringwald {
219*5fd0122aSMatthias Ringwald uint32_t ii;
220*5fd0122aSMatthias Ringwald uint32_t data;
221*5fd0122aSMatthias Ringwald
222*5fd0122aSMatthias Ringwald /* Enabling the correct verification settings */
223*5fd0122aSMatthias Ringwald FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
224*5fd0122aSMatthias Ringwald FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
225*5fd0122aSMatthias Ringwald
226*5fd0122aSMatthias Ringwald data = HWREG32(src);
227*5fd0122aSMatthias Ringwald
228*5fd0122aSMatthias Ringwald for (ii = 0; ii < mTries; ii++)
229*5fd0122aSMatthias Ringwald {
230*5fd0122aSMatthias Ringwald /* Clearing flags */
231*5fd0122aSMatthias Ringwald FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED
232*5fd0122aSMatthias Ringwald | FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE);
233*5fd0122aSMatthias Ringwald
234*5fd0122aSMatthias Ringwald HWREG32(dest) = data;
235*5fd0122aSMatthias Ringwald
236*5fd0122aSMatthias Ringwald while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE))
237*5fd0122aSMatthias Ringwald {
238*5fd0122aSMatthias Ringwald __no_operation();
239*5fd0122aSMatthias Ringwald }
240*5fd0122aSMatthias Ringwald
241*5fd0122aSMatthias Ringwald /* Pre-Verify */
242*5fd0122aSMatthias Ringwald if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS)
243*5fd0122aSMatthias Ringwald && BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS)))
244*5fd0122aSMatthias Ringwald {
245*5fd0122aSMatthias Ringwald data = __FlashCtl_remaskData32Pre(data, dest);
246*5fd0122aSMatthias Ringwald
247*5fd0122aSMatthias Ringwald if (data != 0xFFFFFFFF)
248*5fd0122aSMatthias Ringwald {
249*5fd0122aSMatthias Ringwald
250*5fd0122aSMatthias Ringwald FlashCtl_clearProgramVerification(FLASH_REGPRE);
251*5fd0122aSMatthias Ringwald continue;
252*5fd0122aSMatthias Ringwald }
253*5fd0122aSMatthias Ringwald
254*5fd0122aSMatthias Ringwald }
255*5fd0122aSMatthias Ringwald
256*5fd0122aSMatthias Ringwald /* Post Verify */
257*5fd0122aSMatthias Ringwald if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS)))
258*5fd0122aSMatthias Ringwald {
259*5fd0122aSMatthias Ringwald data = __FlashCtl_remaskData32Post(data, dest);
260*5fd0122aSMatthias Ringwald
261*5fd0122aSMatthias Ringwald /* Seeing if we actually need to do another pulse */
262*5fd0122aSMatthias Ringwald if (data == 0xFFFFFFFF)
263*5fd0122aSMatthias Ringwald return true;
264*5fd0122aSMatthias Ringwald
265*5fd0122aSMatthias Ringwald FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
266*5fd0122aSMatthias Ringwald continue;
267*5fd0122aSMatthias Ringwald }
268*5fd0122aSMatthias Ringwald
269*5fd0122aSMatthias Ringwald /* If we got this far, return true */
270*5fd0122aSMatthias Ringwald return true;
271*5fd0122aSMatthias Ringwald
272*5fd0122aSMatthias Ringwald }
273*5fd0122aSMatthias Ringwald
274*5fd0122aSMatthias Ringwald return false;
275*5fd0122aSMatthias Ringwald
276*5fd0122aSMatthias Ringwald }
277*5fd0122aSMatthias Ringwald
_FlashCtl_ProgramBurst(uint32_t src,uint32_t dest,uint32_t length,uint32_t mTries)278*5fd0122aSMatthias Ringwald static bool _FlashCtl_ProgramBurst(uint32_t src, uint32_t dest, uint32_t length,
279*5fd0122aSMatthias Ringwald uint32_t mTries)
280*5fd0122aSMatthias Ringwald {
281*5fd0122aSMatthias Ringwald uint32_t bCalc, otpOffset, ii, jj;
282*5fd0122aSMatthias Ringwald bool res;
283*5fd0122aSMatthias Ringwald
284*5fd0122aSMatthias Ringwald /* Setting verification */
285*5fd0122aSMatthias Ringwald FlashCtl_clearProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
286*5fd0122aSMatthias Ringwald FlashCtl_setProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
287*5fd0122aSMatthias Ringwald
288*5fd0122aSMatthias Ringwald /* Assume Failure */
289*5fd0122aSMatthias Ringwald res = false;
290*5fd0122aSMatthias Ringwald
291*5fd0122aSMatthias Ringwald /* Waiting for idle status */
292*5fd0122aSMatthias Ringwald while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
293*5fd0122aSMatthias Ringwald != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
294*5fd0122aSMatthias Ringwald {
295*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
296*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
297*5fd0122aSMatthias Ringwald }
298*5fd0122aSMatthias Ringwald
299*5fd0122aSMatthias Ringwald /* Setting/clearing INFO flash flags as appropriate */
300*5fd0122aSMatthias Ringwald if (dest > SysCtl_getFlashSize())
301*5fd0122aSMatthias Ringwald {
302*5fd0122aSMatthias Ringwald FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
303*5fd0122aSMatthias Ringwald & ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_1;
304*5fd0122aSMatthias Ringwald otpOffset = __INFO_FLASH_TECH_START__;
305*5fd0122aSMatthias Ringwald } else
306*5fd0122aSMatthias Ringwald {
307*5fd0122aSMatthias Ringwald FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
308*5fd0122aSMatthias Ringwald & ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_0;
309*5fd0122aSMatthias Ringwald otpOffset = 0;
310*5fd0122aSMatthias Ringwald }
311*5fd0122aSMatthias Ringwald
312*5fd0122aSMatthias Ringwald bCalc = 0;
313*5fd0122aSMatthias Ringwald FLCTL->PRGBRST_STARTADDR = (dest - otpOffset);
314*5fd0122aSMatthias Ringwald
315*5fd0122aSMatthias Ringwald /* Initially populating the burst registers */
316*5fd0122aSMatthias Ringwald while (bCalc < 16 && length != 0)
317*5fd0122aSMatthias Ringwald {
318*5fd0122aSMatthias Ringwald HWREG32(__getBurstProgramRegs[bCalc]) = HWREG32(src);
319*5fd0122aSMatthias Ringwald bCalc++;
320*5fd0122aSMatthias Ringwald length -= 4;
321*5fd0122aSMatthias Ringwald src += 4;
322*5fd0122aSMatthias Ringwald }
323*5fd0122aSMatthias Ringwald
324*5fd0122aSMatthias Ringwald for (ii = 0; ii < mTries; ii++)
325*5fd0122aSMatthias Ringwald {
326*5fd0122aSMatthias Ringwald /* Clearing Flags */
327*5fd0122aSMatthias Ringwald FLCTL->CLRIFG |= (FLASH_BRSTPRGM_COMPLETE | FLASH_POSTVERIFY_FAILED
328*5fd0122aSMatthias Ringwald | FLASH_PREVERIFY_FAILED);
329*5fd0122aSMatthias Ringwald
330*5fd0122aSMatthias Ringwald /* Waiting for idle status */
331*5fd0122aSMatthias Ringwald while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
332*5fd0122aSMatthias Ringwald != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
333*5fd0122aSMatthias Ringwald {
334*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
335*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
336*5fd0122aSMatthias Ringwald }
337*5fd0122aSMatthias Ringwald
338*5fd0122aSMatthias Ringwald /* Start the burst program */
339*5fd0122aSMatthias Ringwald FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
340*5fd0122aSMatthias Ringwald & ~(FLCTL_PRGBRST_CTLSTAT_LEN_MASK))
341*5fd0122aSMatthias Ringwald | ((bCalc / 4) << FLASH_BURST_PRG_BIT)
342*5fd0122aSMatthias Ringwald | FLCTL_PRGBRST_CTLSTAT_START;
343*5fd0122aSMatthias Ringwald
344*5fd0122aSMatthias Ringwald /* Waiting for the burst to complete */
345*5fd0122aSMatthias Ringwald while ((FLCTL->PRGBRST_CTLSTAT &
346*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
347*5fd0122aSMatthias Ringwald != FLASH_PRGBRSTCTLSTAT_BURSTSTATUS_COMPLETE)
348*5fd0122aSMatthias Ringwald {
349*5fd0122aSMatthias Ringwald __no_operation();
350*5fd0122aSMatthias Ringwald }
351*5fd0122aSMatthias Ringwald
352*5fd0122aSMatthias Ringwald /* Checking for errors and clearing/masking */
353*5fd0122aSMatthias Ringwald
354*5fd0122aSMatthias Ringwald /* Address Error */
355*5fd0122aSMatthias Ringwald if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
356*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_ADDR_ERR_OFS))
357*5fd0122aSMatthias Ringwald {
358*5fd0122aSMatthias Ringwald goto BurstCleanUp;
359*5fd0122aSMatthias Ringwald }
360*5fd0122aSMatthias Ringwald
361*5fd0122aSMatthias Ringwald /* Pre-Verify Error */
362*5fd0122aSMatthias Ringwald if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
363*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) && BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
364*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_PRE_ERR_OFS))
365*5fd0122aSMatthias Ringwald {
366*5fd0122aSMatthias Ringwald __FlashCtl_remaskBurstDataPre(dest, bCalc * 4);
367*5fd0122aSMatthias Ringwald
368*5fd0122aSMatthias Ringwald for (jj = 0; jj < bCalc; jj++)
369*5fd0122aSMatthias Ringwald {
370*5fd0122aSMatthias Ringwald if (HWREG32(__getBurstProgramRegs[jj])
371*5fd0122aSMatthias Ringwald != 0xFFFFFFFF)
372*5fd0122aSMatthias Ringwald {
373*5fd0122aSMatthias Ringwald FlashCtl_clearProgramVerification(FLASH_BURSTPRE);
374*5fd0122aSMatthias Ringwald break;
375*5fd0122aSMatthias Ringwald }
376*5fd0122aSMatthias Ringwald }
377*5fd0122aSMatthias Ringwald
378*5fd0122aSMatthias Ringwald if (jj != bCalc)
379*5fd0122aSMatthias Ringwald continue;
380*5fd0122aSMatthias Ringwald }
381*5fd0122aSMatthias Ringwald
382*5fd0122aSMatthias Ringwald /* Post-Verify Error */
383*5fd0122aSMatthias Ringwald if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
384*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_PST_ERR_OFS))
385*5fd0122aSMatthias Ringwald {
386*5fd0122aSMatthias Ringwald __FlashCtl_remaskBurstDataPost(dest, bCalc * 4);
387*5fd0122aSMatthias Ringwald
388*5fd0122aSMatthias Ringwald for (jj = 0; jj < bCalc; jj++)
389*5fd0122aSMatthias Ringwald {
390*5fd0122aSMatthias Ringwald if ((HWREG32(__getBurstProgramRegs[jj]))
391*5fd0122aSMatthias Ringwald != 0xFFFFFFFF)
392*5fd0122aSMatthias Ringwald {
393*5fd0122aSMatthias Ringwald FlashCtl_setProgramVerification(
394*5fd0122aSMatthias Ringwald FLASH_BURSTPOST | FLASH_BURSTPRE);
395*5fd0122aSMatthias Ringwald break;
396*5fd0122aSMatthias Ringwald }
397*5fd0122aSMatthias Ringwald }
398*5fd0122aSMatthias Ringwald
399*5fd0122aSMatthias Ringwald if (jj != bCalc)
400*5fd0122aSMatthias Ringwald continue;
401*5fd0122aSMatthias Ringwald
402*5fd0122aSMatthias Ringwald }
403*5fd0122aSMatthias Ringwald
404*5fd0122aSMatthias Ringwald /* If we got this far, the program happened */
405*5fd0122aSMatthias Ringwald res = true;
406*5fd0122aSMatthias Ringwald goto BurstCleanUp;
407*5fd0122aSMatthias Ringwald }
408*5fd0122aSMatthias Ringwald
409*5fd0122aSMatthias Ringwald BurstCleanUp:
410*5fd0122aSMatthias Ringwald /* Waiting for idle status */
411*5fd0122aSMatthias Ringwald while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
412*5fd0122aSMatthias Ringwald != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
413*5fd0122aSMatthias Ringwald {
414*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
415*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
416*5fd0122aSMatthias Ringwald }
417*5fd0122aSMatthias Ringwald return res;
418*5fd0122aSMatthias Ringwald }
419*5fd0122aSMatthias Ringwald
FlashCtl_enableReadBuffering(uint_fast8_t memoryBank,uint_fast8_t accessMethod)420*5fd0122aSMatthias Ringwald void FlashCtl_enableReadBuffering(uint_fast8_t memoryBank,
421*5fd0122aSMatthias Ringwald uint_fast8_t accessMethod)
422*5fd0122aSMatthias Ringwald {
423*5fd0122aSMatthias Ringwald if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ)
424*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 1;
425*5fd0122aSMatthias Ringwald else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ)
426*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 1;
427*5fd0122aSMatthias Ringwald else if (memoryBank == FLASH_BANK0
428*5fd0122aSMatthias Ringwald && accessMethod == FLASH_INSTRUCTION_FETCH)
429*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 1;
430*5fd0122aSMatthias Ringwald else if (memoryBank == FLASH_BANK1
431*5fd0122aSMatthias Ringwald && accessMethod == FLASH_INSTRUCTION_FETCH)
432*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 1;
433*5fd0122aSMatthias Ringwald else
434*5fd0122aSMatthias Ringwald ASSERT(false);
435*5fd0122aSMatthias Ringwald }
436*5fd0122aSMatthias Ringwald
FlashCtl_disableReadBuffering(uint_fast8_t memoryBank,uint_fast8_t accessMethod)437*5fd0122aSMatthias Ringwald void FlashCtl_disableReadBuffering(uint_fast8_t memoryBank,
438*5fd0122aSMatthias Ringwald uint_fast8_t accessMethod)
439*5fd0122aSMatthias Ringwald {
440*5fd0122aSMatthias Ringwald if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ)
441*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 0;
442*5fd0122aSMatthias Ringwald else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ)
443*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 0;
444*5fd0122aSMatthias Ringwald else if (memoryBank == FLASH_BANK0
445*5fd0122aSMatthias Ringwald && accessMethod == FLASH_INSTRUCTION_FETCH)
446*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 0;
447*5fd0122aSMatthias Ringwald else if (memoryBank == FLASH_BANK1
448*5fd0122aSMatthias Ringwald && accessMethod == FLASH_INSTRUCTION_FETCH)
449*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 0;
450*5fd0122aSMatthias Ringwald else
451*5fd0122aSMatthias Ringwald ASSERT(false);
452*5fd0122aSMatthias Ringwald }
453*5fd0122aSMatthias Ringwald
FlashCtl_unprotectSector(uint_fast8_t memorySpace,uint32_t sectorMask)454*5fd0122aSMatthias Ringwald bool FlashCtl_unprotectSector(uint_fast8_t memorySpace, uint32_t sectorMask)
455*5fd0122aSMatthias Ringwald {
456*5fd0122aSMatthias Ringwald switch (memorySpace)
457*5fd0122aSMatthias Ringwald {
458*5fd0122aSMatthias Ringwald case FLASH_MAIN_MEMORY_SPACE_BANK0:
459*5fd0122aSMatthias Ringwald FLCTL->BANK0_MAIN_WEPROT &= ~sectorMask;
460*5fd0122aSMatthias Ringwald break;
461*5fd0122aSMatthias Ringwald case FLASH_MAIN_MEMORY_SPACE_BANK1:
462*5fd0122aSMatthias Ringwald FLCTL->BANK1_MAIN_WEPROT &= ~sectorMask;
463*5fd0122aSMatthias Ringwald break;
464*5fd0122aSMatthias Ringwald case FLASH_INFO_MEMORY_SPACE_BANK0:
465*5fd0122aSMatthias Ringwald ASSERT(sectorMask <= 0x04);
466*5fd0122aSMatthias Ringwald FLCTL->BANK0_INFO_WEPROT &= ~sectorMask;
467*5fd0122aSMatthias Ringwald break;
468*5fd0122aSMatthias Ringwald case FLASH_INFO_MEMORY_SPACE_BANK1:
469*5fd0122aSMatthias Ringwald ASSERT(sectorMask <= 0x04);
470*5fd0122aSMatthias Ringwald FLCTL->BANK1_INFO_WEPROT &= ~sectorMask;
471*5fd0122aSMatthias Ringwald break;
472*5fd0122aSMatthias Ringwald
473*5fd0122aSMatthias Ringwald default:
474*5fd0122aSMatthias Ringwald ASSERT(false);
475*5fd0122aSMatthias Ringwald
476*5fd0122aSMatthias Ringwald }
477*5fd0122aSMatthias Ringwald
478*5fd0122aSMatthias Ringwald return !FlashCtl_isSectorProtected(memorySpace, sectorMask);
479*5fd0122aSMatthias Ringwald }
480*5fd0122aSMatthias Ringwald
FlashCtl_protectSector(uint_fast8_t memorySpace,uint32_t sectorMask)481*5fd0122aSMatthias Ringwald bool FlashCtl_protectSector(uint_fast8_t memorySpace, uint32_t sectorMask)
482*5fd0122aSMatthias Ringwald {
483*5fd0122aSMatthias Ringwald switch (memorySpace)
484*5fd0122aSMatthias Ringwald {
485*5fd0122aSMatthias Ringwald case FLASH_MAIN_MEMORY_SPACE_BANK0:
486*5fd0122aSMatthias Ringwald FLCTL->BANK0_MAIN_WEPROT |= sectorMask;
487*5fd0122aSMatthias Ringwald break;
488*5fd0122aSMatthias Ringwald case FLASH_MAIN_MEMORY_SPACE_BANK1:
489*5fd0122aSMatthias Ringwald FLCTL->BANK1_MAIN_WEPROT |= sectorMask;
490*5fd0122aSMatthias Ringwald break;
491*5fd0122aSMatthias Ringwald case FLASH_INFO_MEMORY_SPACE_BANK0:
492*5fd0122aSMatthias Ringwald ASSERT(sectorMask <= 0x03);
493*5fd0122aSMatthias Ringwald FLCTL->BANK0_INFO_WEPROT |= sectorMask;
494*5fd0122aSMatthias Ringwald break;
495*5fd0122aSMatthias Ringwald case FLASH_INFO_MEMORY_SPACE_BANK1:
496*5fd0122aSMatthias Ringwald ASSERT(sectorMask <= 0x03);
497*5fd0122aSMatthias Ringwald FLCTL->BANK1_INFO_WEPROT |= sectorMask;
498*5fd0122aSMatthias Ringwald break;
499*5fd0122aSMatthias Ringwald
500*5fd0122aSMatthias Ringwald default:
501*5fd0122aSMatthias Ringwald ASSERT(false);
502*5fd0122aSMatthias Ringwald
503*5fd0122aSMatthias Ringwald }
504*5fd0122aSMatthias Ringwald
505*5fd0122aSMatthias Ringwald return FlashCtl_isSectorProtected(memorySpace, sectorMask);
506*5fd0122aSMatthias Ringwald }
507*5fd0122aSMatthias Ringwald
FlashCtl_isSectorProtected(uint_fast8_t memorySpace,uint32_t sector)508*5fd0122aSMatthias Ringwald bool FlashCtl_isSectorProtected(uint_fast8_t memorySpace, uint32_t sector)
509*5fd0122aSMatthias Ringwald {
510*5fd0122aSMatthias Ringwald switch (memorySpace)
511*5fd0122aSMatthias Ringwald {
512*5fd0122aSMatthias Ringwald case FLASH_MAIN_MEMORY_SPACE_BANK0:
513*5fd0122aSMatthias Ringwald return FLCTL->BANK0_MAIN_WEPROT & sector;
514*5fd0122aSMatthias Ringwald case FLASH_MAIN_MEMORY_SPACE_BANK1:
515*5fd0122aSMatthias Ringwald return FLCTL->BANK1_MAIN_WEPROT & sector;
516*5fd0122aSMatthias Ringwald case FLASH_INFO_MEMORY_SPACE_BANK0:
517*5fd0122aSMatthias Ringwald ASSERT(sector <= 0x04);
518*5fd0122aSMatthias Ringwald return FLCTL->BANK0_INFO_WEPROT & sector;
519*5fd0122aSMatthias Ringwald case FLASH_INFO_MEMORY_SPACE_BANK1:
520*5fd0122aSMatthias Ringwald ASSERT(sector <= 0x04);
521*5fd0122aSMatthias Ringwald return FLCTL->BANK1_INFO_WEPROT & sector;
522*5fd0122aSMatthias Ringwald default:
523*5fd0122aSMatthias Ringwald return false;
524*5fd0122aSMatthias Ringwald }
525*5fd0122aSMatthias Ringwald }
526*5fd0122aSMatthias Ringwald
FlashCtl_verifyMemory(void * verifyAddr,uint32_t length,uint_fast8_t pattern)527*5fd0122aSMatthias Ringwald bool FlashCtl_verifyMemory(void* verifyAddr, uint32_t length,
528*5fd0122aSMatthias Ringwald uint_fast8_t pattern)
529*5fd0122aSMatthias Ringwald {
530*5fd0122aSMatthias Ringwald uint32_t memoryPattern, addr, otpOffset;
531*5fd0122aSMatthias Ringwald uint32_t b0WaitState, b1WaitState, intStatus;
532*5fd0122aSMatthias Ringwald uint32_t bankOneStart, startBank, endBank;
533*5fd0122aSMatthias Ringwald uint_fast8_t b0readMode, b1readMode;
534*5fd0122aSMatthias Ringwald uint_fast8_t memoryType;
535*5fd0122aSMatthias Ringwald bool res;
536*5fd0122aSMatthias Ringwald
537*5fd0122aSMatthias Ringwald ASSERT(pattern == FLASH_0_PATTERN || pattern == FLASH_1_PATTERN);
538*5fd0122aSMatthias Ringwald
539*5fd0122aSMatthias Ringwald /* Saving interrupt context and disabling interrupts for program
540*5fd0122aSMatthias Ringwald * operation
541*5fd0122aSMatthias Ringwald */
542*5fd0122aSMatthias Ringwald intStatus = CPU_primask();
543*5fd0122aSMatthias Ringwald Interrupt_disableMaster();
544*5fd0122aSMatthias Ringwald
545*5fd0122aSMatthias Ringwald /* Casting and determining the memory that we need to use */
546*5fd0122aSMatthias Ringwald addr = (uint32_t) verifyAddr;
547*5fd0122aSMatthias Ringwald memoryType =
548*5fd0122aSMatthias Ringwald (addr > SysCtl_getFlashSize()) ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
549*5fd0122aSMatthias Ringwald
550*5fd0122aSMatthias Ringwald /* Assuming Failure */
551*5fd0122aSMatthias Ringwald res = false;
552*5fd0122aSMatthias Ringwald
553*5fd0122aSMatthias Ringwald /* Finding out which bank we are in */
554*5fd0122aSMatthias Ringwald if(addr > SysCtl_getFlashSize())
555*5fd0122aSMatthias Ringwald {
556*5fd0122aSMatthias Ringwald bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
557*5fd0122aSMatthias Ringwald }
558*5fd0122aSMatthias Ringwald else
559*5fd0122aSMatthias Ringwald {
560*5fd0122aSMatthias Ringwald bankOneStart = SysCtl_getFlashSize() / 2;
561*5fd0122aSMatthias Ringwald }
562*5fd0122aSMatthias Ringwald startBank = addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
563*5fd0122aSMatthias Ringwald endBank = (addr + length) < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
564*5fd0122aSMatthias Ringwald
565*5fd0122aSMatthias Ringwald /* Saving context and changing read modes */
566*5fd0122aSMatthias Ringwald b0WaitState = FlashCtl_getWaitState(startBank);
567*5fd0122aSMatthias Ringwald b0readMode = FlashCtl_getReadMode(startBank);
568*5fd0122aSMatthias Ringwald
569*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
570*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(startBank, (2 * b0WaitState) + 1);
571*5fd0122aSMatthias Ringwald
572*5fd0122aSMatthias Ringwald if(startBank != endBank)
573*5fd0122aSMatthias Ringwald {
574*5fd0122aSMatthias Ringwald b1WaitState = FlashCtl_getWaitState(endBank);
575*5fd0122aSMatthias Ringwald b1readMode = FlashCtl_getReadMode(endBank);
576*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(endBank, (2 * b1WaitState) + 1);
577*5fd0122aSMatthias Ringwald }
578*5fd0122aSMatthias Ringwald
579*5fd0122aSMatthias Ringwald /* Changing to the relevant VERIFY mode */
580*5fd0122aSMatthias Ringwald if (pattern == FLASH_1_PATTERN)
581*5fd0122aSMatthias Ringwald {
582*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(startBank, FLASH_ERASE_VERIFY_READ_MODE);
583*5fd0122aSMatthias Ringwald
584*5fd0122aSMatthias Ringwald if(startBank != endBank)
585*5fd0122aSMatthias Ringwald {
586*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(endBank, FLASH_ERASE_VERIFY_READ_MODE);
587*5fd0122aSMatthias Ringwald }
588*5fd0122aSMatthias Ringwald
589*5fd0122aSMatthias Ringwald memoryPattern = 0xFFFFFFFF;
590*5fd0122aSMatthias Ringwald } else
591*5fd0122aSMatthias Ringwald {
592*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(startBank, FLASH_PROGRAM_VERIFY_READ_MODE);
593*5fd0122aSMatthias Ringwald
594*5fd0122aSMatthias Ringwald if(startBank != endBank)
595*5fd0122aSMatthias Ringwald {
596*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(endBank, FLASH_PROGRAM_VERIFY_READ_MODE);
597*5fd0122aSMatthias Ringwald }
598*5fd0122aSMatthias Ringwald
599*5fd0122aSMatthias Ringwald memoryPattern = 0;
600*5fd0122aSMatthias Ringwald }
601*5fd0122aSMatthias Ringwald
602*5fd0122aSMatthias Ringwald /* Taking care of byte accesses */
603*5fd0122aSMatthias Ringwald while ((addr & 0x03) && (length > 0))
604*5fd0122aSMatthias Ringwald {
605*5fd0122aSMatthias Ringwald if (HWREG8(addr++) != ((uint8_t) memoryPattern))
606*5fd0122aSMatthias Ringwald goto FlashVerifyCleanup;
607*5fd0122aSMatthias Ringwald length--;
608*5fd0122aSMatthias Ringwald }
609*5fd0122aSMatthias Ringwald
610*5fd0122aSMatthias Ringwald /* Making sure we are aligned by 128-bit address */
611*5fd0122aSMatthias Ringwald while (((addr & 0x0F)) && (length > 3))
612*5fd0122aSMatthias Ringwald {
613*5fd0122aSMatthias Ringwald if (HWREG32(addr) != memoryPattern)
614*5fd0122aSMatthias Ringwald goto FlashVerifyCleanup;
615*5fd0122aSMatthias Ringwald
616*5fd0122aSMatthias Ringwald addr = addr + 4;
617*5fd0122aSMatthias Ringwald length = length - 4;
618*5fd0122aSMatthias Ringwald }
619*5fd0122aSMatthias Ringwald
620*5fd0122aSMatthias Ringwald /* Burst Verify */
621*5fd0122aSMatthias Ringwald if (length > 63)
622*5fd0122aSMatthias Ringwald {
623*5fd0122aSMatthias Ringwald /* Setting/clearing INFO flash flags as appropriate */
624*5fd0122aSMatthias Ringwald if (addr > SysCtl_getFlashSize())
625*5fd0122aSMatthias Ringwald {
626*5fd0122aSMatthias Ringwald FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT
627*5fd0122aSMatthias Ringwald & ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK)
628*5fd0122aSMatthias Ringwald | FLCTL_RDBRST_CTLSTAT_MEM_TYPE_1;
629*5fd0122aSMatthias Ringwald otpOffset = __INFO_FLASH_TECH_START__;
630*5fd0122aSMatthias Ringwald } else
631*5fd0122aSMatthias Ringwald {
632*5fd0122aSMatthias Ringwald FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT
633*5fd0122aSMatthias Ringwald & ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK)
634*5fd0122aSMatthias Ringwald | FLCTL_RDBRST_CTLSTAT_MEM_TYPE_0;
635*5fd0122aSMatthias Ringwald otpOffset = 0;
636*5fd0122aSMatthias Ringwald }
637*5fd0122aSMatthias Ringwald
638*5fd0122aSMatthias Ringwald /* Clearing any lingering fault flags and preparing burst verify*/
639*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
640*5fd0122aSMatthias Ringwald FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1;
641*5fd0122aSMatthias Ringwald FLCTL->RDBRST_FAILCNT = 0;
642*5fd0122aSMatthias Ringwald FLCTL->RDBRST_STARTADDR = addr - otpOffset;
643*5fd0122aSMatthias Ringwald FLCTL->RDBRST_LEN = (length & 0xFFFFFFF0);
644*5fd0122aSMatthias Ringwald addr += FLCTL->RDBRST_LEN;
645*5fd0122aSMatthias Ringwald length = length & 0xF;
646*5fd0122aSMatthias Ringwald
647*5fd0122aSMatthias Ringwald /* Starting Burst Verify */
648*5fd0122aSMatthias Ringwald FLCTL->RDBRST_CTLSTAT = (FLCTL_RDBRST_CTLSTAT_STOP_FAIL | pattern
649*5fd0122aSMatthias Ringwald | memoryType | FLCTL_RDBRST_CTLSTAT_START);
650*5fd0122aSMatthias Ringwald
651*5fd0122aSMatthias Ringwald /* While the burst read hasn't finished */
652*5fd0122aSMatthias Ringwald while ((FLCTL->RDBRST_CTLSTAT & FLCTL_RDBRST_CTLSTAT_BRST_STAT_MASK)
653*5fd0122aSMatthias Ringwald != FLCTL_RDBRST_CTLSTAT_BRST_STAT_3)
654*5fd0122aSMatthias Ringwald {
655*5fd0122aSMatthias Ringwald __no_operation();
656*5fd0122aSMatthias Ringwald }
657*5fd0122aSMatthias Ringwald
658*5fd0122aSMatthias Ringwald /* Checking for a verification/access error/failure */
659*5fd0122aSMatthias Ringwald if (BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
660*5fd0122aSMatthias Ringwald FLCTL_RDBRST_CTLSTAT_CMP_ERR_OFS)
661*5fd0122aSMatthias Ringwald || BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
662*5fd0122aSMatthias Ringwald FLCTL_RDBRST_CTLSTAT_ADDR_ERR_OFS)
663*5fd0122aSMatthias Ringwald || FLCTL->RDBRST_FAILCNT)
664*5fd0122aSMatthias Ringwald {
665*5fd0122aSMatthias Ringwald goto FlashVerifyCleanup;
666*5fd0122aSMatthias Ringwald }
667*5fd0122aSMatthias Ringwald }
668*5fd0122aSMatthias Ringwald
669*5fd0122aSMatthias Ringwald /* Remaining Words */
670*5fd0122aSMatthias Ringwald while (length > 3)
671*5fd0122aSMatthias Ringwald {
672*5fd0122aSMatthias Ringwald if (HWREG32(addr) != memoryPattern)
673*5fd0122aSMatthias Ringwald goto FlashVerifyCleanup;
674*5fd0122aSMatthias Ringwald
675*5fd0122aSMatthias Ringwald addr = addr + 4;
676*5fd0122aSMatthias Ringwald length = length - 4;
677*5fd0122aSMatthias Ringwald }
678*5fd0122aSMatthias Ringwald
679*5fd0122aSMatthias Ringwald /* Remaining Bytes */
680*5fd0122aSMatthias Ringwald while (length > 0)
681*5fd0122aSMatthias Ringwald {
682*5fd0122aSMatthias Ringwald if (HWREG8(addr++) != ((uint8_t) memoryPattern))
683*5fd0122aSMatthias Ringwald goto FlashVerifyCleanup;
684*5fd0122aSMatthias Ringwald length--;
685*5fd0122aSMatthias Ringwald }
686*5fd0122aSMatthias Ringwald
687*5fd0122aSMatthias Ringwald /* If we got this far, that means it no failure happened */
688*5fd0122aSMatthias Ringwald res = true;
689*5fd0122aSMatthias Ringwald
690*5fd0122aSMatthias Ringwald FlashVerifyCleanup:
691*5fd0122aSMatthias Ringwald
692*5fd0122aSMatthias Ringwald /* Clearing the Read Burst flag and returning */
693*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
694*5fd0122aSMatthias Ringwald FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1;
695*5fd0122aSMatthias Ringwald
696*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(startBank, b0readMode);
697*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(startBank, b0WaitState);
698*5fd0122aSMatthias Ringwald
699*5fd0122aSMatthias Ringwald if(startBank != endBank)
700*5fd0122aSMatthias Ringwald {
701*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(endBank, b1readMode);
702*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(endBank, b1WaitState);
703*5fd0122aSMatthias Ringwald }
704*5fd0122aSMatthias Ringwald
705*5fd0122aSMatthias Ringwald if(intStatus == 0)
706*5fd0122aSMatthias Ringwald Interrupt_enableMaster();
707*5fd0122aSMatthias Ringwald
708*5fd0122aSMatthias Ringwald return res;
709*5fd0122aSMatthias Ringwald }
710*5fd0122aSMatthias Ringwald
FlashCtl_setReadMode(uint32_t flashBank,uint32_t readMode)711*5fd0122aSMatthias Ringwald bool FlashCtl_setReadMode(uint32_t flashBank, uint32_t readMode)
712*5fd0122aSMatthias Ringwald {
713*5fd0122aSMatthias Ringwald
714*5fd0122aSMatthias Ringwald if (FLCTL->POWER_STAT & FLCTL_POWER_STAT_RD_2T)
715*5fd0122aSMatthias Ringwald return false;
716*5fd0122aSMatthias Ringwald
717*5fd0122aSMatthias Ringwald if (flashBank == FLASH_BANK0)
718*5fd0122aSMatthias Ringwald {
719*5fd0122aSMatthias Ringwald FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL
720*5fd0122aSMatthias Ringwald & ~FLCTL_BANK0_RDCTL_RD_MODE_MASK) | readMode;
721*5fd0122aSMatthias Ringwald while ((FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_STATUS_MASK)
722*5fd0122aSMatthias Ringwald != (readMode<<16))
723*5fd0122aSMatthias Ringwald ;
724*5fd0122aSMatthias Ringwald } else if (flashBank == FLASH_BANK1)
725*5fd0122aSMatthias Ringwald {
726*5fd0122aSMatthias Ringwald FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL
727*5fd0122aSMatthias Ringwald & ~FLCTL_BANK1_RDCTL_RD_MODE_MASK) | readMode;
728*5fd0122aSMatthias Ringwald while ((FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_STATUS_MASK)
729*5fd0122aSMatthias Ringwald != (readMode<<16))
730*5fd0122aSMatthias Ringwald ;
731*5fd0122aSMatthias Ringwald } else
732*5fd0122aSMatthias Ringwald {
733*5fd0122aSMatthias Ringwald ASSERT(false);
734*5fd0122aSMatthias Ringwald return false;
735*5fd0122aSMatthias Ringwald }
736*5fd0122aSMatthias Ringwald
737*5fd0122aSMatthias Ringwald return true;
738*5fd0122aSMatthias Ringwald }
739*5fd0122aSMatthias Ringwald
FlashCtl_getReadMode(uint32_t flashBank)740*5fd0122aSMatthias Ringwald uint32_t FlashCtl_getReadMode(uint32_t flashBank)
741*5fd0122aSMatthias Ringwald {
742*5fd0122aSMatthias Ringwald if (flashBank == FLASH_BANK0)
743*5fd0122aSMatthias Ringwald {
744*5fd0122aSMatthias Ringwald return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_STATUS_MASK) >> 16;
745*5fd0122aSMatthias Ringwald } else if (flashBank == FLASH_BANK1)
746*5fd0122aSMatthias Ringwald {
747*5fd0122aSMatthias Ringwald return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_STATUS_MASK) >> 16;
748*5fd0122aSMatthias Ringwald } else
749*5fd0122aSMatthias Ringwald {
750*5fd0122aSMatthias Ringwald ASSERT(false);
751*5fd0122aSMatthias Ringwald return 0;
752*5fd0122aSMatthias Ringwald }
753*5fd0122aSMatthias Ringwald }
754*5fd0122aSMatthias Ringwald
FlashCtl_initiateMassErase(void)755*5fd0122aSMatthias Ringwald void FlashCtl_initiateMassErase(void)
756*5fd0122aSMatthias Ringwald {
757*5fd0122aSMatthias Ringwald /* Clearing old mass erase flags */
758*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
759*5fd0122aSMatthias Ringwald
760*5fd0122aSMatthias Ringwald /* Performing the mass erase */
761*5fd0122aSMatthias Ringwald FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE
762*5fd0122aSMatthias Ringwald | FLCTL_ERASE_CTLSTAT_START);
763*5fd0122aSMatthias Ringwald }
764*5fd0122aSMatthias Ringwald
FlashCtl_performMassErase(void)765*5fd0122aSMatthias Ringwald bool FlashCtl_performMassErase(void)
766*5fd0122aSMatthias Ringwald {
767*5fd0122aSMatthias Ringwald uint32_t userFlash, ii, sector, intStatus;
768*5fd0122aSMatthias Ringwald bool res;
769*5fd0122aSMatthias Ringwald
770*5fd0122aSMatthias Ringwald /* Saving interrupt context and disabling interrupts for program
771*5fd0122aSMatthias Ringwald * operation
772*5fd0122aSMatthias Ringwald */
773*5fd0122aSMatthias Ringwald intStatus = CPU_primask();
774*5fd0122aSMatthias Ringwald Interrupt_disableMaster();
775*5fd0122aSMatthias Ringwald
776*5fd0122aSMatthias Ringwald /* Assume Failure */
777*5fd0122aSMatthias Ringwald res = false;
778*5fd0122aSMatthias Ringwald
779*5fd0122aSMatthias Ringwald /* Clearing old mass erase flags */
780*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
781*5fd0122aSMatthias Ringwald
782*5fd0122aSMatthias Ringwald /* Performing the mass erase */
783*5fd0122aSMatthias Ringwald FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE
784*5fd0122aSMatthias Ringwald | FLCTL_ERASE_CTLSTAT_START);
785*5fd0122aSMatthias Ringwald
786*5fd0122aSMatthias Ringwald while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
787*5fd0122aSMatthias Ringwald == FLCTL_ERASE_CTLSTAT_STATUS_1
788*5fd0122aSMatthias Ringwald || (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
789*5fd0122aSMatthias Ringwald == FLCTL_ERASE_CTLSTAT_STATUS_2)
790*5fd0122aSMatthias Ringwald {
791*5fd0122aSMatthias Ringwald __no_operation();
792*5fd0122aSMatthias Ringwald }
793*5fd0122aSMatthias Ringwald
794*5fd0122aSMatthias Ringwald /* Return false if an address error */
795*5fd0122aSMatthias Ringwald if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS))
796*5fd0122aSMatthias Ringwald goto MassEraseCleanup;
797*5fd0122aSMatthias Ringwald
798*5fd0122aSMatthias Ringwald /* Changing to erase verify */
799*5fd0122aSMatthias Ringwald userFlash = SysCtl_getFlashSize() / 2;
800*5fd0122aSMatthias Ringwald
801*5fd0122aSMatthias Ringwald for (ii = 0; ii < userFlash; ii += 4096)
802*5fd0122aSMatthias Ringwald {
803*5fd0122aSMatthias Ringwald sector = getUserFlashSector(ii);
804*5fd0122aSMatthias Ringwald
805*5fd0122aSMatthias Ringwald if (!((FLCTL->BANK0_MAIN_WEPROT) & sector))
806*5fd0122aSMatthias Ringwald {
807*5fd0122aSMatthias Ringwald if (!FlashCtl_verifyMemory((void*) ii, 4096, FLASH_1_PATTERN))
808*5fd0122aSMatthias Ringwald {
809*5fd0122aSMatthias Ringwald if (!FlashCtl_eraseSector(ii))
810*5fd0122aSMatthias Ringwald goto MassEraseCleanup;
811*5fd0122aSMatthias Ringwald }
812*5fd0122aSMatthias Ringwald }
813*5fd0122aSMatthias Ringwald
814*5fd0122aSMatthias Ringwald if (!(FLCTL->BANK1_MAIN_WEPROT & sector))
815*5fd0122aSMatthias Ringwald {
816*5fd0122aSMatthias Ringwald if (!FlashCtl_verifyMemory((void*) (ii + userFlash), 4096,
817*5fd0122aSMatthias Ringwald FLASH_1_PATTERN))
818*5fd0122aSMatthias Ringwald {
819*5fd0122aSMatthias Ringwald if (!FlashCtl_eraseSector(ii + userFlash))
820*5fd0122aSMatthias Ringwald goto MassEraseCleanup;
821*5fd0122aSMatthias Ringwald }
822*5fd0122aSMatthias Ringwald }
823*5fd0122aSMatthias Ringwald
824*5fd0122aSMatthias Ringwald if (sector < FLCTL_BANK0_MAIN_WEPROT_PROT2)
825*5fd0122aSMatthias Ringwald {
826*5fd0122aSMatthias Ringwald if (!(FLCTL->BANK0_INFO_WEPROT & sector))
827*5fd0122aSMatthias Ringwald {
828*5fd0122aSMatthias Ringwald if (!FlashCtl_verifyMemory(
829*5fd0122aSMatthias Ringwald (void*) (ii + __INFO_FLASH_TECH_START__), 4096,
830*5fd0122aSMatthias Ringwald FLASH_1_PATTERN))
831*5fd0122aSMatthias Ringwald {
832*5fd0122aSMatthias Ringwald if (!FlashCtl_eraseSector(ii + __INFO_FLASH_TECH_START__))
833*5fd0122aSMatthias Ringwald goto MassEraseCleanup;
834*5fd0122aSMatthias Ringwald }
835*5fd0122aSMatthias Ringwald }
836*5fd0122aSMatthias Ringwald
837*5fd0122aSMatthias Ringwald if (!(FLCTL->BANK1_INFO_WEPROT & sector))
838*5fd0122aSMatthias Ringwald {
839*5fd0122aSMatthias Ringwald if (!FlashCtl_verifyMemory((void*) (ii + (0x202000)), 4096,
840*5fd0122aSMatthias Ringwald FLASH_1_PATTERN))
841*5fd0122aSMatthias Ringwald {
842*5fd0122aSMatthias Ringwald if (!FlashCtl_eraseSector(ii + (0x202000)))
843*5fd0122aSMatthias Ringwald goto MassEraseCleanup;
844*5fd0122aSMatthias Ringwald }
845*5fd0122aSMatthias Ringwald }
846*5fd0122aSMatthias Ringwald
847*5fd0122aSMatthias Ringwald }
848*5fd0122aSMatthias Ringwald }
849*5fd0122aSMatthias Ringwald
850*5fd0122aSMatthias Ringwald /* If we got this far, the mass erase happened */
851*5fd0122aSMatthias Ringwald res = true;
852*5fd0122aSMatthias Ringwald
853*5fd0122aSMatthias Ringwald MassEraseCleanup:
854*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
855*5fd0122aSMatthias Ringwald
856*5fd0122aSMatthias Ringwald if(intStatus == 0)
857*5fd0122aSMatthias Ringwald Interrupt_enableMaster();
858*5fd0122aSMatthias Ringwald
859*5fd0122aSMatthias Ringwald return res;
860*5fd0122aSMatthias Ringwald }
861*5fd0122aSMatthias Ringwald
FlashCtl_eraseSector(uint32_t addr)862*5fd0122aSMatthias Ringwald bool FlashCtl_eraseSector(uint32_t addr)
863*5fd0122aSMatthias Ringwald {
864*5fd0122aSMatthias Ringwald uint_fast8_t memoryType, ii;
865*5fd0122aSMatthias Ringwald uint32_t otpOffset = 0;
866*5fd0122aSMatthias Ringwald uint32_t intStatus;
867*5fd0122aSMatthias Ringwald uint_fast8_t mTries, tlvLength;
868*5fd0122aSMatthias Ringwald SysCtl_FlashTLV_Info *flInfo;
869*5fd0122aSMatthias Ringwald bool res;
870*5fd0122aSMatthias Ringwald
871*5fd0122aSMatthias Ringwald /* Saving interrupt context and disabling interrupts for program
872*5fd0122aSMatthias Ringwald * operation
873*5fd0122aSMatthias Ringwald */
874*5fd0122aSMatthias Ringwald intStatus = CPU_primask();
875*5fd0122aSMatthias Ringwald Interrupt_disableMaster();
876*5fd0122aSMatthias Ringwald
877*5fd0122aSMatthias Ringwald /* Assuming Failure */
878*5fd0122aSMatthias Ringwald res = false;
879*5fd0122aSMatthias Ringwald
880*5fd0122aSMatthias Ringwald memoryType =
881*5fd0122aSMatthias Ringwald addr > SysCtl_getFlashSize() ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
882*5fd0122aSMatthias Ringwald
883*5fd0122aSMatthias Ringwald /* Parsing the TLV and getting the maximum erase pulses */
884*5fd0122aSMatthias Ringwald SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
885*5fd0122aSMatthias Ringwald
886*5fd0122aSMatthias Ringwald if (tlvLength == 0 || flInfo->maxErasePulses == 0)
887*5fd0122aSMatthias Ringwald {
888*5fd0122aSMatthias Ringwald mTries = MAX_ERASE_NO_TLV;
889*5fd0122aSMatthias Ringwald } else
890*5fd0122aSMatthias Ringwald {
891*5fd0122aSMatthias Ringwald mTries = flInfo->maxErasePulses;
892*5fd0122aSMatthias Ringwald }
893*5fd0122aSMatthias Ringwald
894*5fd0122aSMatthias Ringwald /* We can only erase on 4KB boundaries */
895*5fd0122aSMatthias Ringwald while (addr & 0xFFF)
896*5fd0122aSMatthias Ringwald {
897*5fd0122aSMatthias Ringwald addr--;
898*5fd0122aSMatthias Ringwald }
899*5fd0122aSMatthias Ringwald
900*5fd0122aSMatthias Ringwald /* Clearing the status */
901*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
902*5fd0122aSMatthias Ringwald
903*5fd0122aSMatthias Ringwald if (memoryType == FLASH_INFO_SPACE)
904*5fd0122aSMatthias Ringwald {
905*5fd0122aSMatthias Ringwald otpOffset = __INFO_FLASH_TECH_START__;
906*5fd0122aSMatthias Ringwald FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
907*5fd0122aSMatthias Ringwald & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1;
908*5fd0122aSMatthias Ringwald
909*5fd0122aSMatthias Ringwald } else
910*5fd0122aSMatthias Ringwald {
911*5fd0122aSMatthias Ringwald otpOffset = 0;
912*5fd0122aSMatthias Ringwald FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
913*5fd0122aSMatthias Ringwald & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0;
914*5fd0122aSMatthias Ringwald }
915*5fd0122aSMatthias Ringwald
916*5fd0122aSMatthias Ringwald /* Clearing old flags and setting up the erase */
917*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0;
918*5fd0122aSMatthias Ringwald FLCTL->ERASE_SECTADDR = addr - otpOffset;
919*5fd0122aSMatthias Ringwald
920*5fd0122aSMatthias Ringwald for (ii = 0; ii < mTries; ii++)
921*5fd0122aSMatthias Ringwald {
922*5fd0122aSMatthias Ringwald /* Clearing the status */
923*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) =
924*5fd0122aSMatthias Ringwald 1;
925*5fd0122aSMatthias Ringwald
926*5fd0122aSMatthias Ringwald /* Starting the erase */
927*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
928*5fd0122aSMatthias Ringwald FLCTL_ERASE_CTLSTAT_START_OFS) = 1;
929*5fd0122aSMatthias Ringwald
930*5fd0122aSMatthias Ringwald while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
931*5fd0122aSMatthias Ringwald == FLCTL_ERASE_CTLSTAT_STATUS_1
932*5fd0122aSMatthias Ringwald || (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
933*5fd0122aSMatthias Ringwald == FLCTL_ERASE_CTLSTAT_STATUS_2)
934*5fd0122aSMatthias Ringwald {
935*5fd0122aSMatthias Ringwald __no_operation();
936*5fd0122aSMatthias Ringwald }
937*5fd0122aSMatthias Ringwald
938*5fd0122aSMatthias Ringwald /* Return false if an address error */
939*5fd0122aSMatthias Ringwald if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
940*5fd0122aSMatthias Ringwald FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS))
941*5fd0122aSMatthias Ringwald {
942*5fd0122aSMatthias Ringwald goto SectorEraseCleanup;
943*5fd0122aSMatthias Ringwald }
944*5fd0122aSMatthias Ringwald /* Erase verifying */
945*5fd0122aSMatthias Ringwald if (FlashCtl_verifyMemory((void*) addr, 4096, FLASH_1_PATTERN))
946*5fd0122aSMatthias Ringwald {
947*5fd0122aSMatthias Ringwald res = true;
948*5fd0122aSMatthias Ringwald goto SectorEraseCleanup;
949*5fd0122aSMatthias Ringwald }
950*5fd0122aSMatthias Ringwald
951*5fd0122aSMatthias Ringwald }
952*5fd0122aSMatthias Ringwald
953*5fd0122aSMatthias Ringwald SectorEraseCleanup:
954*5fd0122aSMatthias Ringwald
955*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
956*5fd0122aSMatthias Ringwald
957*5fd0122aSMatthias Ringwald if(intStatus == 0)
958*5fd0122aSMatthias Ringwald Interrupt_enableMaster();
959*5fd0122aSMatthias Ringwald
960*5fd0122aSMatthias Ringwald return res;
961*5fd0122aSMatthias Ringwald }
962*5fd0122aSMatthias Ringwald
FlashCtl_initiateSectorErase(uint32_t addr)963*5fd0122aSMatthias Ringwald void FlashCtl_initiateSectorErase(uint32_t addr)
964*5fd0122aSMatthias Ringwald {
965*5fd0122aSMatthias Ringwald uint_fast8_t memoryType;
966*5fd0122aSMatthias Ringwald uint32_t otpOffset = 0;
967*5fd0122aSMatthias Ringwald
968*5fd0122aSMatthias Ringwald memoryType =
969*5fd0122aSMatthias Ringwald addr > SysCtl_getFlashSize() ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
970*5fd0122aSMatthias Ringwald
971*5fd0122aSMatthias Ringwald /* We can only erase on 4KB boundaries */
972*5fd0122aSMatthias Ringwald while (addr & 0xFFF)
973*5fd0122aSMatthias Ringwald {
974*5fd0122aSMatthias Ringwald addr--;
975*5fd0122aSMatthias Ringwald }
976*5fd0122aSMatthias Ringwald
977*5fd0122aSMatthias Ringwald /* Clearing the status */
978*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
979*5fd0122aSMatthias Ringwald
980*5fd0122aSMatthias Ringwald if (memoryType == FLASH_INFO_SPACE)
981*5fd0122aSMatthias Ringwald {
982*5fd0122aSMatthias Ringwald otpOffset = __INFO_FLASH_TECH_START__;
983*5fd0122aSMatthias Ringwald FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
984*5fd0122aSMatthias Ringwald & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1;
985*5fd0122aSMatthias Ringwald
986*5fd0122aSMatthias Ringwald } else
987*5fd0122aSMatthias Ringwald {
988*5fd0122aSMatthias Ringwald otpOffset = 0;
989*5fd0122aSMatthias Ringwald FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
990*5fd0122aSMatthias Ringwald & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0;
991*5fd0122aSMatthias Ringwald }
992*5fd0122aSMatthias Ringwald
993*5fd0122aSMatthias Ringwald /* Clearing old flags and setting up the erase */
994*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0;
995*5fd0122aSMatthias Ringwald FLCTL->ERASE_SECTADDR = addr - otpOffset;
996*5fd0122aSMatthias Ringwald
997*5fd0122aSMatthias Ringwald /* Starting the erase */
998*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
999*5fd0122aSMatthias Ringwald FLCTL_ERASE_CTLSTAT_START_OFS) = 1;
1000*5fd0122aSMatthias Ringwald
1001*5fd0122aSMatthias Ringwald }
1002*5fd0122aSMatthias Ringwald
FlashCtl_programMemory(void * src,void * dest,uint32_t length)1003*5fd0122aSMatthias Ringwald bool FlashCtl_programMemory(void* src, void* dest, uint32_t length)
1004*5fd0122aSMatthias Ringwald {
1005*5fd0122aSMatthias Ringwald uint32_t destAddr, srcAddr, burstLength, intStatus;
1006*5fd0122aSMatthias Ringwald bool res;
1007*5fd0122aSMatthias Ringwald uint_fast8_t mTries, tlvLength;
1008*5fd0122aSMatthias Ringwald SysCtl_FlashTLV_Info *flInfo;
1009*5fd0122aSMatthias Ringwald
1010*5fd0122aSMatthias Ringwald /* Saving interrupt context and disabling interrupts for program
1011*5fd0122aSMatthias Ringwald * operation
1012*5fd0122aSMatthias Ringwald */
1013*5fd0122aSMatthias Ringwald intStatus = CPU_primask();
1014*5fd0122aSMatthias Ringwald Interrupt_disableMaster();
1015*5fd0122aSMatthias Ringwald
1016*5fd0122aSMatthias Ringwald /* Parsing the TLV and getting the maximum erase pulses */
1017*5fd0122aSMatthias Ringwald SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
1018*5fd0122aSMatthias Ringwald
1019*5fd0122aSMatthias Ringwald if (tlvLength == 0 || flInfo->maxProgramPulses == 0)
1020*5fd0122aSMatthias Ringwald {
1021*5fd0122aSMatthias Ringwald mTries = MAX_PROGRAM_NO_TLV;
1022*5fd0122aSMatthias Ringwald } else
1023*5fd0122aSMatthias Ringwald {
1024*5fd0122aSMatthias Ringwald mTries = flInfo->maxProgramPulses;
1025*5fd0122aSMatthias Ringwald }
1026*5fd0122aSMatthias Ringwald
1027*5fd0122aSMatthias Ringwald /* Casting to integers */
1028*5fd0122aSMatthias Ringwald srcAddr = (uint32_t) src;
1029*5fd0122aSMatthias Ringwald destAddr = (uint32_t) dest;
1030*5fd0122aSMatthias Ringwald
1031*5fd0122aSMatthias Ringwald /* Enabling word programming */
1032*5fd0122aSMatthias Ringwald FlashCtl_enableWordProgramming(FLASH_IMMEDIATE_WRITE_MODE);
1033*5fd0122aSMatthias Ringwald
1034*5fd0122aSMatthias Ringwald /* Assume failure */
1035*5fd0122aSMatthias Ringwald res = false;
1036*5fd0122aSMatthias Ringwald
1037*5fd0122aSMatthias Ringwald /* Taking care of byte accesses */
1038*5fd0122aSMatthias Ringwald while ((destAddr & 0x03) && length > 0)
1039*5fd0122aSMatthias Ringwald {
1040*5fd0122aSMatthias Ringwald if (!_FlashCtl_Program8(srcAddr, destAddr, mTries))
1041*5fd0122aSMatthias Ringwald {
1042*5fd0122aSMatthias Ringwald goto FlashProgramCleanUp;
1043*5fd0122aSMatthias Ringwald } else
1044*5fd0122aSMatthias Ringwald {
1045*5fd0122aSMatthias Ringwald srcAddr++;
1046*5fd0122aSMatthias Ringwald destAddr++;
1047*5fd0122aSMatthias Ringwald length--;
1048*5fd0122aSMatthias Ringwald }
1049*5fd0122aSMatthias Ringwald }
1050*5fd0122aSMatthias Ringwald
1051*5fd0122aSMatthias Ringwald /* Taking care of word accesses */
1052*5fd0122aSMatthias Ringwald while ((destAddr & 0x0F) && (length > 3))
1053*5fd0122aSMatthias Ringwald {
1054*5fd0122aSMatthias Ringwald if (!_FlashCtl_Program32(srcAddr, destAddr, mTries))
1055*5fd0122aSMatthias Ringwald {
1056*5fd0122aSMatthias Ringwald goto FlashProgramCleanUp;
1057*5fd0122aSMatthias Ringwald } else
1058*5fd0122aSMatthias Ringwald {
1059*5fd0122aSMatthias Ringwald srcAddr += 4;
1060*5fd0122aSMatthias Ringwald destAddr += 4;
1061*5fd0122aSMatthias Ringwald length -= 4;
1062*5fd0122aSMatthias Ringwald }
1063*5fd0122aSMatthias Ringwald }
1064*5fd0122aSMatthias Ringwald
1065*5fd0122aSMatthias Ringwald /* Taking care of burst programs */
1066*5fd0122aSMatthias Ringwald while (length > 16)
1067*5fd0122aSMatthias Ringwald {
1068*5fd0122aSMatthias Ringwald burstLength = length > 63 ? 64 : length & 0xFFFFFFF0;
1069*5fd0122aSMatthias Ringwald
1070*5fd0122aSMatthias Ringwald if (!_FlashCtl_ProgramBurst(srcAddr, destAddr, burstLength, mTries))
1071*5fd0122aSMatthias Ringwald {
1072*5fd0122aSMatthias Ringwald goto FlashProgramCleanUp;
1073*5fd0122aSMatthias Ringwald } else
1074*5fd0122aSMatthias Ringwald {
1075*5fd0122aSMatthias Ringwald srcAddr += burstLength;
1076*5fd0122aSMatthias Ringwald destAddr += burstLength;
1077*5fd0122aSMatthias Ringwald length -= burstLength;
1078*5fd0122aSMatthias Ringwald }
1079*5fd0122aSMatthias Ringwald }
1080*5fd0122aSMatthias Ringwald
1081*5fd0122aSMatthias Ringwald /* Remaining word accesses */
1082*5fd0122aSMatthias Ringwald while (length > 3)
1083*5fd0122aSMatthias Ringwald {
1084*5fd0122aSMatthias Ringwald if (!_FlashCtl_Program32(srcAddr, destAddr, mTries))
1085*5fd0122aSMatthias Ringwald {
1086*5fd0122aSMatthias Ringwald goto FlashProgramCleanUp;
1087*5fd0122aSMatthias Ringwald } else
1088*5fd0122aSMatthias Ringwald {
1089*5fd0122aSMatthias Ringwald srcAddr+=4;
1090*5fd0122aSMatthias Ringwald destAddr+=4;
1091*5fd0122aSMatthias Ringwald length-=4;
1092*5fd0122aSMatthias Ringwald }
1093*5fd0122aSMatthias Ringwald }
1094*5fd0122aSMatthias Ringwald
1095*5fd0122aSMatthias Ringwald /* Remaining byte accesses */
1096*5fd0122aSMatthias Ringwald while (length > 0)
1097*5fd0122aSMatthias Ringwald {
1098*5fd0122aSMatthias Ringwald if (!_FlashCtl_Program8(srcAddr, destAddr, mTries))
1099*5fd0122aSMatthias Ringwald {
1100*5fd0122aSMatthias Ringwald goto FlashProgramCleanUp;
1101*5fd0122aSMatthias Ringwald } else
1102*5fd0122aSMatthias Ringwald {
1103*5fd0122aSMatthias Ringwald srcAddr++;
1104*5fd0122aSMatthias Ringwald destAddr++;
1105*5fd0122aSMatthias Ringwald length--;
1106*5fd0122aSMatthias Ringwald }
1107*5fd0122aSMatthias Ringwald }
1108*5fd0122aSMatthias Ringwald
1109*5fd0122aSMatthias Ringwald /* If we got this far that means that we succeeded */
1110*5fd0122aSMatthias Ringwald res = true;
1111*5fd0122aSMatthias Ringwald
1112*5fd0122aSMatthias Ringwald FlashProgramCleanUp:
1113*5fd0122aSMatthias Ringwald
1114*5fd0122aSMatthias Ringwald if(intStatus == 0)
1115*5fd0122aSMatthias Ringwald Interrupt_enableMaster();
1116*5fd0122aSMatthias Ringwald
1117*5fd0122aSMatthias Ringwald FlashCtl_disableWordProgramming();
1118*5fd0122aSMatthias Ringwald return res;
1119*5fd0122aSMatthias Ringwald
1120*5fd0122aSMatthias Ringwald }
FlashCtl_setProgramVerification(uint32_t verificationSetting)1121*5fd0122aSMatthias Ringwald void FlashCtl_setProgramVerification(uint32_t verificationSetting)
1122*5fd0122aSMatthias Ringwald {
1123*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_BURSTPOST))
1124*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1125*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 1;
1126*5fd0122aSMatthias Ringwald
1127*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_BURSTPRE))
1128*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1129*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 1;
1130*5fd0122aSMatthias Ringwald
1131*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_REGPRE))
1132*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 1;
1133*5fd0122aSMatthias Ringwald
1134*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_REGPOST))
1135*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 1;
1136*5fd0122aSMatthias Ringwald }
1137*5fd0122aSMatthias Ringwald
FlashCtl_clearProgramVerification(uint32_t verificationSetting)1138*5fd0122aSMatthias Ringwald void FlashCtl_clearProgramVerification(uint32_t verificationSetting)
1139*5fd0122aSMatthias Ringwald {
1140*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_BURSTPOST))
1141*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1142*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 0;
1143*5fd0122aSMatthias Ringwald
1144*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_BURSTPRE))
1145*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1146*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 0;
1147*5fd0122aSMatthias Ringwald
1148*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_REGPRE))
1149*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 0;
1150*5fd0122aSMatthias Ringwald
1151*5fd0122aSMatthias Ringwald if ((verificationSetting & FLASH_REGPOST))
1152*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 0;
1153*5fd0122aSMatthias Ringwald
1154*5fd0122aSMatthias Ringwald }
1155*5fd0122aSMatthias Ringwald
FlashCtl_enableWordProgramming(uint32_t mode)1156*5fd0122aSMatthias Ringwald void FlashCtl_enableWordProgramming(uint32_t mode)
1157*5fd0122aSMatthias Ringwald {
1158*5fd0122aSMatthias Ringwald if (mode == FLASH_IMMEDIATE_WRITE_MODE)
1159*5fd0122aSMatthias Ringwald {
1160*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1;
1161*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 0;
1162*5fd0122aSMatthias Ringwald
1163*5fd0122aSMatthias Ringwald } else if (mode == FLASH_COLLATED_WRITE_MODE)
1164*5fd0122aSMatthias Ringwald {
1165*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1;
1166*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 1;
1167*5fd0122aSMatthias Ringwald }
1168*5fd0122aSMatthias Ringwald }
1169*5fd0122aSMatthias Ringwald
FlashCtl_disableWordProgramming(void)1170*5fd0122aSMatthias Ringwald void FlashCtl_disableWordProgramming(void)
1171*5fd0122aSMatthias Ringwald {
1172*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 0;
1173*5fd0122aSMatthias Ringwald }
1174*5fd0122aSMatthias Ringwald
FlashCtl_isWordProgrammingEnabled(void)1175*5fd0122aSMatthias Ringwald uint32_t FlashCtl_isWordProgrammingEnabled(void)
1176*5fd0122aSMatthias Ringwald {
1177*5fd0122aSMatthias Ringwald if (!BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS))
1178*5fd0122aSMatthias Ringwald {
1179*5fd0122aSMatthias Ringwald return 0;
1180*5fd0122aSMatthias Ringwald } else if (BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS))
1181*5fd0122aSMatthias Ringwald return FLASH_COLLATED_WRITE_MODE;
1182*5fd0122aSMatthias Ringwald else
1183*5fd0122aSMatthias Ringwald return FLASH_IMMEDIATE_WRITE_MODE;
1184*5fd0122aSMatthias Ringwald }
1185*5fd0122aSMatthias Ringwald
FlashCtl_setWaitState(uint32_t flashBank,uint32_t waitState)1186*5fd0122aSMatthias Ringwald void FlashCtl_setWaitState(uint32_t flashBank, uint32_t waitState)
1187*5fd0122aSMatthias Ringwald {
1188*5fd0122aSMatthias Ringwald if (flashBank == FLASH_BANK0)
1189*5fd0122aSMatthias Ringwald {
1190*5fd0122aSMatthias Ringwald FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL
1191*5fd0122aSMatthias Ringwald & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK0_RDCTL_WAIT_OFS);
1192*5fd0122aSMatthias Ringwald } else if (flashBank == FLASH_BANK1)
1193*5fd0122aSMatthias Ringwald {
1194*5fd0122aSMatthias Ringwald FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL
1195*5fd0122aSMatthias Ringwald & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK1_RDCTL_WAIT_OFS);
1196*5fd0122aSMatthias Ringwald } else
1197*5fd0122aSMatthias Ringwald {
1198*5fd0122aSMatthias Ringwald ASSERT(false);
1199*5fd0122aSMatthias Ringwald }
1200*5fd0122aSMatthias Ringwald }
1201*5fd0122aSMatthias Ringwald
FlashCtl_getWaitState(uint32_t flashBank)1202*5fd0122aSMatthias Ringwald uint32_t FlashCtl_getWaitState(uint32_t flashBank)
1203*5fd0122aSMatthias Ringwald {
1204*5fd0122aSMatthias Ringwald if (flashBank == FLASH_BANK0)
1205*5fd0122aSMatthias Ringwald {
1206*5fd0122aSMatthias Ringwald return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_WAIT_MASK) >> FLCTL_BANK0_RDCTL_WAIT_OFS;
1207*5fd0122aSMatthias Ringwald } else if (flashBank == FLASH_BANK1)
1208*5fd0122aSMatthias Ringwald {
1209*5fd0122aSMatthias Ringwald return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_WAIT_MASK) >> FLCTL_BANK1_RDCTL_WAIT_OFS;
1210*5fd0122aSMatthias Ringwald } else
1211*5fd0122aSMatthias Ringwald {
1212*5fd0122aSMatthias Ringwald ASSERT(false);
1213*5fd0122aSMatthias Ringwald return 0;
1214*5fd0122aSMatthias Ringwald }
1215*5fd0122aSMatthias Ringwald }
1216*5fd0122aSMatthias Ringwald
FlashCtl_enableInterrupt(uint32_t flags)1217*5fd0122aSMatthias Ringwald void FlashCtl_enableInterrupt(uint32_t flags)
1218*5fd0122aSMatthias Ringwald {
1219*5fd0122aSMatthias Ringwald FLCTL->IE |= flags;
1220*5fd0122aSMatthias Ringwald }
1221*5fd0122aSMatthias Ringwald
FlashCtl_disableInterrupt(uint32_t flags)1222*5fd0122aSMatthias Ringwald void FlashCtl_disableInterrupt(uint32_t flags)
1223*5fd0122aSMatthias Ringwald {
1224*5fd0122aSMatthias Ringwald FLCTL->IE &= ~flags;
1225*5fd0122aSMatthias Ringwald }
1226*5fd0122aSMatthias Ringwald
FlashCtl_getInterruptStatus(void)1227*5fd0122aSMatthias Ringwald uint32_t FlashCtl_getInterruptStatus(void)
1228*5fd0122aSMatthias Ringwald {
1229*5fd0122aSMatthias Ringwald return FLCTL->IFG;
1230*5fd0122aSMatthias Ringwald }
1231*5fd0122aSMatthias Ringwald
FlashCtl_getEnabledInterruptStatus(void)1232*5fd0122aSMatthias Ringwald uint32_t FlashCtl_getEnabledInterruptStatus(void)
1233*5fd0122aSMatthias Ringwald {
1234*5fd0122aSMatthias Ringwald return FlashCtl_getInterruptStatus() & FLCTL->IE;
1235*5fd0122aSMatthias Ringwald }
1236*5fd0122aSMatthias Ringwald
FlashCtl_clearInterruptFlag(uint32_t flags)1237*5fd0122aSMatthias Ringwald void FlashCtl_clearInterruptFlag(uint32_t flags)
1238*5fd0122aSMatthias Ringwald {
1239*5fd0122aSMatthias Ringwald FLCTL->CLRIFG |= flags;
1240*5fd0122aSMatthias Ringwald }
1241*5fd0122aSMatthias Ringwald
FlashCtl_registerInterrupt(void (* intHandler)(void))1242*5fd0122aSMatthias Ringwald void FlashCtl_registerInterrupt(void (*intHandler)(void))
1243*5fd0122aSMatthias Ringwald {
1244*5fd0122aSMatthias Ringwald //
1245*5fd0122aSMatthias Ringwald // Register the interrupt handler, returning an error if an error occurs.
1246*5fd0122aSMatthias Ringwald //
1247*5fd0122aSMatthias Ringwald Interrupt_registerInterrupt(INT_FLCTL, intHandler);
1248*5fd0122aSMatthias Ringwald
1249*5fd0122aSMatthias Ringwald //
1250*5fd0122aSMatthias Ringwald // Enable the system control interrupt.
1251*5fd0122aSMatthias Ringwald //
1252*5fd0122aSMatthias Ringwald Interrupt_enableInterrupt(INT_FLCTL);
1253*5fd0122aSMatthias Ringwald }
1254*5fd0122aSMatthias Ringwald
FlashCtl_unregisterInterrupt(void)1255*5fd0122aSMatthias Ringwald void FlashCtl_unregisterInterrupt(void)
1256*5fd0122aSMatthias Ringwald {
1257*5fd0122aSMatthias Ringwald //
1258*5fd0122aSMatthias Ringwald // Disable the interrupt.
1259*5fd0122aSMatthias Ringwald //
1260*5fd0122aSMatthias Ringwald Interrupt_disableInterrupt(INT_FLCTL);
1261*5fd0122aSMatthias Ringwald
1262*5fd0122aSMatthias Ringwald //
1263*5fd0122aSMatthias Ringwald // Unregister the interrupt handler.
1264*5fd0122aSMatthias Ringwald //
1265*5fd0122aSMatthias Ringwald Interrupt_unregisterInterrupt(INT_FLCTL);
1266*5fd0122aSMatthias Ringwald }
1267*5fd0122aSMatthias Ringwald
__FlashCtl_remaskData8Post(uint8_t data,uint32_t addr)1268*5fd0122aSMatthias Ringwald uint8_t __FlashCtl_remaskData8Post(uint8_t data, uint32_t addr)
1269*5fd0122aSMatthias Ringwald {
1270*5fd0122aSMatthias Ringwald uint32_t readMode, waitState, bankProgram, bankOneStart;
1271*5fd0122aSMatthias Ringwald
1272*5fd0122aSMatthias Ringwald /* Changing the waitstate and read mode of whichever bank we are in */
1273*5fd0122aSMatthias Ringwald /* Finding out which bank we are in */
1274*5fd0122aSMatthias Ringwald if(addr > SysCtl_getFlashSize())
1275*5fd0122aSMatthias Ringwald {
1276*5fd0122aSMatthias Ringwald bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
1277*5fd0122aSMatthias Ringwald }
1278*5fd0122aSMatthias Ringwald else
1279*5fd0122aSMatthias Ringwald {
1280*5fd0122aSMatthias Ringwald bankOneStart = SysCtl_getFlashSize() / 2;
1281*5fd0122aSMatthias Ringwald }
1282*5fd0122aSMatthias Ringwald
1283*5fd0122aSMatthias Ringwald bankProgram =
1284*5fd0122aSMatthias Ringwald addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
1285*5fd0122aSMatthias Ringwald
1286*5fd0122aSMatthias Ringwald /* Saving the current wait states and read mode */
1287*5fd0122aSMatthias Ringwald waitState = FlashCtl_getWaitState(bankProgram);
1288*5fd0122aSMatthias Ringwald readMode = FlashCtl_getReadMode(bankProgram);
1289*5fd0122aSMatthias Ringwald
1290*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1291*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1);
1292*5fd0122aSMatthias Ringwald
1293*5fd0122aSMatthias Ringwald /* Changing to PROGRAM VERIFY mode */
1294*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE);
1295*5fd0122aSMatthias Ringwald
1296*5fd0122aSMatthias Ringwald data = ~(~(data) & HWREG8(addr));
1297*5fd0122aSMatthias Ringwald
1298*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1299*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgram, readMode);
1300*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgram, waitState);
1301*5fd0122aSMatthias Ringwald
1302*5fd0122aSMatthias Ringwald return data;
1303*5fd0122aSMatthias Ringwald }
1304*5fd0122aSMatthias Ringwald
__FlashCtl_remaskData8Pre(uint8_t data,uint32_t addr)1305*5fd0122aSMatthias Ringwald uint8_t __FlashCtl_remaskData8Pre(uint8_t data, uint32_t addr)
1306*5fd0122aSMatthias Ringwald {
1307*5fd0122aSMatthias Ringwald uint32_t readMode, waitState, bankProgram, bankOneStart;
1308*5fd0122aSMatthias Ringwald
1309*5fd0122aSMatthias Ringwald /* Changing the waitstate and read mode of whichever bank we are in */
1310*5fd0122aSMatthias Ringwald /* Finding out which bank we are in */
1311*5fd0122aSMatthias Ringwald if(addr > SysCtl_getFlashSize())
1312*5fd0122aSMatthias Ringwald {
1313*5fd0122aSMatthias Ringwald bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
1314*5fd0122aSMatthias Ringwald }
1315*5fd0122aSMatthias Ringwald else
1316*5fd0122aSMatthias Ringwald {
1317*5fd0122aSMatthias Ringwald bankOneStart = SysCtl_getFlashSize() / 2;
1318*5fd0122aSMatthias Ringwald }
1319*5fd0122aSMatthias Ringwald
1320*5fd0122aSMatthias Ringwald bankProgram =
1321*5fd0122aSMatthias Ringwald addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
1322*5fd0122aSMatthias Ringwald
1323*5fd0122aSMatthias Ringwald /* Saving the current wait states and read mode */
1324*5fd0122aSMatthias Ringwald waitState = FlashCtl_getWaitState(bankProgram);
1325*5fd0122aSMatthias Ringwald readMode = FlashCtl_getReadMode(bankProgram);
1326*5fd0122aSMatthias Ringwald
1327*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1328*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1);
1329*5fd0122aSMatthias Ringwald
1330*5fd0122aSMatthias Ringwald /* Changing to PROGRAM VERIFY mode */
1331*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE);
1332*5fd0122aSMatthias Ringwald
1333*5fd0122aSMatthias Ringwald data |= ~(HWREG8(addr) | data);
1334*5fd0122aSMatthias Ringwald
1335*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1336*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgram, readMode);
1337*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgram, waitState);
1338*5fd0122aSMatthias Ringwald
1339*5fd0122aSMatthias Ringwald return data;
1340*5fd0122aSMatthias Ringwald }
1341*5fd0122aSMatthias Ringwald
__FlashCtl_remaskData32Post(uint32_t data,uint32_t addr)1342*5fd0122aSMatthias Ringwald uint32_t __FlashCtl_remaskData32Post(uint32_t data, uint32_t addr)
1343*5fd0122aSMatthias Ringwald {
1344*5fd0122aSMatthias Ringwald uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1345*5fd0122aSMatthias Ringwald uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1346*5fd0122aSMatthias Ringwald
1347*5fd0122aSMatthias Ringwald /* Changing the waitstate and read mode of whichever bank we are in */
1348*5fd0122aSMatthias Ringwald /* Finding out which bank we are in */
1349*5fd0122aSMatthias Ringwald if(addr > SysCtl_getFlashSize())
1350*5fd0122aSMatthias Ringwald {
1351*5fd0122aSMatthias Ringwald bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1352*5fd0122aSMatthias Ringwald }
1353*5fd0122aSMatthias Ringwald else
1354*5fd0122aSMatthias Ringwald {
1355*5fd0122aSMatthias Ringwald bank1Start = SysCtl_getFlashSize() / 2;
1356*5fd0122aSMatthias Ringwald }
1357*5fd0122aSMatthias Ringwald
1358*5fd0122aSMatthias Ringwald bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1359*5fd0122aSMatthias Ringwald bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1360*5fd0122aSMatthias Ringwald
1361*5fd0122aSMatthias Ringwald /* Saving the current wait states and read mode */
1362*5fd0122aSMatthias Ringwald b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1363*5fd0122aSMatthias Ringwald b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1364*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1365*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1366*5fd0122aSMatthias Ringwald
1367*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1368*5fd0122aSMatthias Ringwald {
1369*5fd0122aSMatthias Ringwald b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1370*5fd0122aSMatthias Ringwald b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1371*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1372*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1373*5fd0122aSMatthias Ringwald }
1374*5fd0122aSMatthias Ringwald
1375*5fd0122aSMatthias Ringwald data = ~(~(data) & HWREG32(addr));
1376*5fd0122aSMatthias Ringwald
1377*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1378*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1379*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1380*5fd0122aSMatthias Ringwald
1381*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1382*5fd0122aSMatthias Ringwald {
1383*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1384*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1385*5fd0122aSMatthias Ringwald }
1386*5fd0122aSMatthias Ringwald
1387*5fd0122aSMatthias Ringwald return data;
1388*5fd0122aSMatthias Ringwald }
1389*5fd0122aSMatthias Ringwald
__FlashCtl_remaskData32Pre(uint32_t data,uint32_t addr)1390*5fd0122aSMatthias Ringwald uint32_t __FlashCtl_remaskData32Pre(uint32_t data, uint32_t addr)
1391*5fd0122aSMatthias Ringwald {
1392*5fd0122aSMatthias Ringwald uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1393*5fd0122aSMatthias Ringwald uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1394*5fd0122aSMatthias Ringwald
1395*5fd0122aSMatthias Ringwald /* Changing the waitstate and read mode of whichever bank we are in */
1396*5fd0122aSMatthias Ringwald /* Finding out which bank we are in */
1397*5fd0122aSMatthias Ringwald if(addr > SysCtl_getFlashSize())
1398*5fd0122aSMatthias Ringwald {
1399*5fd0122aSMatthias Ringwald bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1400*5fd0122aSMatthias Ringwald }
1401*5fd0122aSMatthias Ringwald else
1402*5fd0122aSMatthias Ringwald {
1403*5fd0122aSMatthias Ringwald bank1Start = SysCtl_getFlashSize() / 2;
1404*5fd0122aSMatthias Ringwald }
1405*5fd0122aSMatthias Ringwald
1406*5fd0122aSMatthias Ringwald bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1407*5fd0122aSMatthias Ringwald bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1408*5fd0122aSMatthias Ringwald
1409*5fd0122aSMatthias Ringwald /* Saving the current wait states and read mode */
1410*5fd0122aSMatthias Ringwald b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1411*5fd0122aSMatthias Ringwald b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1412*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1413*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1414*5fd0122aSMatthias Ringwald
1415*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1416*5fd0122aSMatthias Ringwald {
1417*5fd0122aSMatthias Ringwald b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1418*5fd0122aSMatthias Ringwald b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1419*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1420*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1421*5fd0122aSMatthias Ringwald }
1422*5fd0122aSMatthias Ringwald
1423*5fd0122aSMatthias Ringwald data |= ~(HWREG32(addr) | data);
1424*5fd0122aSMatthias Ringwald
1425*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1426*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1427*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1428*5fd0122aSMatthias Ringwald
1429*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1430*5fd0122aSMatthias Ringwald {
1431*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1432*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1433*5fd0122aSMatthias Ringwald }
1434*5fd0122aSMatthias Ringwald
1435*5fd0122aSMatthias Ringwald return data;
1436*5fd0122aSMatthias Ringwald }
1437*5fd0122aSMatthias Ringwald
__FlashCtl_remaskBurstDataPre(uint32_t addr,uint32_t size)1438*5fd0122aSMatthias Ringwald void __FlashCtl_remaskBurstDataPre(uint32_t addr, uint32_t size)
1439*5fd0122aSMatthias Ringwald {
1440*5fd0122aSMatthias Ringwald
1441*5fd0122aSMatthias Ringwald uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1442*5fd0122aSMatthias Ringwald uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1443*5fd0122aSMatthias Ringwald
1444*5fd0122aSMatthias Ringwald /* Waiting for idle status */
1445*5fd0122aSMatthias Ringwald while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1446*5fd0122aSMatthias Ringwald != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
1447*5fd0122aSMatthias Ringwald {
1448*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1449*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1450*5fd0122aSMatthias Ringwald }
1451*5fd0122aSMatthias Ringwald
1452*5fd0122aSMatthias Ringwald /* Changing the waitstate and read mode of whichever bank we are in */
1453*5fd0122aSMatthias Ringwald /* Finding out which bank we are in */
1454*5fd0122aSMatthias Ringwald if(addr > SysCtl_getFlashSize())
1455*5fd0122aSMatthias Ringwald {
1456*5fd0122aSMatthias Ringwald bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1457*5fd0122aSMatthias Ringwald }
1458*5fd0122aSMatthias Ringwald else
1459*5fd0122aSMatthias Ringwald {
1460*5fd0122aSMatthias Ringwald bank1Start = SysCtl_getFlashSize() / 2;
1461*5fd0122aSMatthias Ringwald }
1462*5fd0122aSMatthias Ringwald
1463*5fd0122aSMatthias Ringwald bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1464*5fd0122aSMatthias Ringwald bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1465*5fd0122aSMatthias Ringwald
1466*5fd0122aSMatthias Ringwald /* Saving the current wait states and read mode */
1467*5fd0122aSMatthias Ringwald b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1468*5fd0122aSMatthias Ringwald b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1469*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1470*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1471*5fd0122aSMatthias Ringwald
1472*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1473*5fd0122aSMatthias Ringwald {
1474*5fd0122aSMatthias Ringwald b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1475*5fd0122aSMatthias Ringwald b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1476*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1477*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1478*5fd0122aSMatthias Ringwald }
1479*5fd0122aSMatthias Ringwald
1480*5fd0122aSMatthias Ringwald /* Going through each BURST program register and masking out for pre
1481*5fd0122aSMatthias Ringwald * verifcation
1482*5fd0122aSMatthias Ringwald */
1483*5fd0122aSMatthias Ringwald size = (size / 4);
1484*5fd0122aSMatthias Ringwald for (ii = 0; ii < size; ii++)
1485*5fd0122aSMatthias Ringwald {
1486*5fd0122aSMatthias Ringwald uint32_t temp1 = HWREG32(__getBurstProgramRegs[ii]);
1487*5fd0122aSMatthias Ringwald uint32_t temp2 = HWREG32(addr);
1488*5fd0122aSMatthias Ringwald HWREG32(__getBurstProgramRegs[ii]) |= ~(temp1 | temp2);
1489*5fd0122aSMatthias Ringwald addr += 4;
1490*5fd0122aSMatthias Ringwald }
1491*5fd0122aSMatthias Ringwald
1492*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1493*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1494*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1495*5fd0122aSMatthias Ringwald
1496*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1497*5fd0122aSMatthias Ringwald {
1498*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1499*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1500*5fd0122aSMatthias Ringwald }
1501*5fd0122aSMatthias Ringwald
1502*5fd0122aSMatthias Ringwald }
__FlashCtl_remaskBurstDataPost(uint32_t addr,uint32_t size)1503*5fd0122aSMatthias Ringwald void __FlashCtl_remaskBurstDataPost(uint32_t addr, uint32_t size)
1504*5fd0122aSMatthias Ringwald {
1505*5fd0122aSMatthias Ringwald uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1506*5fd0122aSMatthias Ringwald uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1507*5fd0122aSMatthias Ringwald
1508*5fd0122aSMatthias Ringwald /* Waiting for idle status */
1509*5fd0122aSMatthias Ringwald while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1510*5fd0122aSMatthias Ringwald != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
1511*5fd0122aSMatthias Ringwald {
1512*5fd0122aSMatthias Ringwald BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1513*5fd0122aSMatthias Ringwald FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1514*5fd0122aSMatthias Ringwald }
1515*5fd0122aSMatthias Ringwald
1516*5fd0122aSMatthias Ringwald /* Changing the waitstate and read mode of whichever bank we are in */
1517*5fd0122aSMatthias Ringwald /* Finding out which bank we are in */
1518*5fd0122aSMatthias Ringwald if(addr > SysCtl_getFlashSize())
1519*5fd0122aSMatthias Ringwald {
1520*5fd0122aSMatthias Ringwald bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1521*5fd0122aSMatthias Ringwald }
1522*5fd0122aSMatthias Ringwald else
1523*5fd0122aSMatthias Ringwald {
1524*5fd0122aSMatthias Ringwald bank1Start = SysCtl_getFlashSize() / 2;
1525*5fd0122aSMatthias Ringwald }
1526*5fd0122aSMatthias Ringwald
1527*5fd0122aSMatthias Ringwald bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1528*5fd0122aSMatthias Ringwald bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1529*5fd0122aSMatthias Ringwald
1530*5fd0122aSMatthias Ringwald /* Saving the current wait states and read mode */
1531*5fd0122aSMatthias Ringwald b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1532*5fd0122aSMatthias Ringwald b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1533*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1534*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1535*5fd0122aSMatthias Ringwald
1536*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1537*5fd0122aSMatthias Ringwald {
1538*5fd0122aSMatthias Ringwald b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1539*5fd0122aSMatthias Ringwald b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1540*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1541*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1542*5fd0122aSMatthias Ringwald }
1543*5fd0122aSMatthias Ringwald
1544*5fd0122aSMatthias Ringwald /* Going through each BURST program register and masking out for post
1545*5fd0122aSMatthias Ringwald * verifcation if needed
1546*5fd0122aSMatthias Ringwald */
1547*5fd0122aSMatthias Ringwald size = (size / 4);
1548*5fd0122aSMatthias Ringwald for (ii = 0; ii < size; ii++)
1549*5fd0122aSMatthias Ringwald {
1550*5fd0122aSMatthias Ringwald uint32_t temp1 = (HWREG32(__getBurstProgramRegs[ii]));
1551*5fd0122aSMatthias Ringwald uint32_t temp2 = HWREG32(addr);
1552*5fd0122aSMatthias Ringwald HWREG32(__getBurstProgramRegs[ii]) = ~(~temp1 & temp2);
1553*5fd0122aSMatthias Ringwald
1554*5fd0122aSMatthias Ringwald addr += 4;
1555*5fd0122aSMatthias Ringwald }
1556*5fd0122aSMatthias Ringwald
1557*5fd0122aSMatthias Ringwald /* Setting the wait state to account for the mode */
1558*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1559*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1560*5fd0122aSMatthias Ringwald
1561*5fd0122aSMatthias Ringwald if (bankProgramStart != bankProgramEnd)
1562*5fd0122aSMatthias Ringwald {
1563*5fd0122aSMatthias Ringwald FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1564*5fd0122aSMatthias Ringwald FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1565*5fd0122aSMatthias Ringwald }
1566*5fd0122aSMatthias Ringwald }
1567*5fd0122aSMatthias Ringwald
1568*5fd0122aSMatthias Ringwald #endif /* __MCU_HAS_FLCTL__ */
1569