MCCI Trusted Bootloader
Simple trusted bootloader and tools for small embedded systems
mccibootloader_stm32l0_systemflash.c
Go to the documentation of this file.
1/*
2
3Module: mccibootloader_stm32l0_systemflash.c
4
5Function:
6 McciBootloader_Stm32L0_systemFlashErase() and
7 McciBootloader_Stm32L0_systemFlashWrite()
8
9Copyright and License:
10 This file copyright (C) 2021 by
11
12 MCCI Corporation
13 3520 Krums Corners Road
14 Ithaca, NY 14850
15
16 See accompanying LICENSE file for copyright and license information.
17
18Author:
19 Terry Moore, MCCI Corporation March 2021
20
21*/
22
23
25#include "mcci_stm32l0xx.h"
26
27/****************************************************************************\
28|
29| Manifest constants & typedefs.
30|
31\****************************************************************************/
32
33bool
35 uint32_t flash_addr,
36 const uint32_t *pData
37 );
38
39/****************************************************************************\
40|
41| Read-only data.
42|
43\****************************************************************************/
44
45
46
47/****************************************************************************\
48|
49| Variables.
50|
51\****************************************************************************/
52
53bool
55 volatile const void *pBase,
56 size_t nBytes
57 )
58 {
59 bool result = true;
60
61 // round nBytes up if necessary for partial pages.
62 nBytes = (nBytes + MCCI_STM32L0_FLASH_PAGE_SIZE - 1) & ~(MCCI_STM32L0_FLASH_PAGE_SIZE - 1);
63
64 // wait
66 /* loop */;
67
68 // unlock the PECR bit
71
72 // unlock the PROG bit
75
76 // loop throgh each page, erasing
77 uint32_t p;
78 size_t nPages;
79
80 p = (uint32_t)pBase;
81 nPages = nBytes / MCCI_STM32L0_FLASH_PAGE_SIZE;
82
86 );
87
88 for (; nPages > 0; p += MCCI_STM32L0_FLASH_PAGE_SIZE, --nPages)
89 {
90 // start the erase
91 McciArm_putReg(p, 0);
92
93 // wait for done
95 /* loop */;
96
97 // reset EOP
102 );
103 }
104
105 // turn off PECR bits
109 );
110
111 // lock
113 return result;
114 }
115
116bool
117__attribute__((__section__(".RamFunc")))
119 uint32_t flash_addr,
120 const uint32_t *pData
121 )
122 {
127 );
128
129 unsigned i;
130 for (i = 0; i < MCCI_STM32L0_FLASH_HALF_PAGE_SIZE; i += sizeof(uint32_t), ++pData)
131 {
132 McciArm_putReg(flash_addr + i, *pData);
133 }
134
135 // wait for done
137 /* loop */;
138
139 // reset EOP
144 );
145
146 // turn off PECR bits
151 );
152
153 return true;
154 }
155
156bool
158 volatile const void *pDest,
159 const void *pSrc,
160 size_t nBytes
161 )
162 {
163 bool result;
164 uint32_t srcAddr = (uint32_t)pSrc;
165 if ((srcAddr & 3) != 0)
166 return false;
167
168 if ((nBytes % MCCI_STM32L0_FLASH_HALF_PAGE_SIZE) != 0)
169 return false;
170
171 uint32_t destAddr = (uint32_t)pDest;
172 if ((destAddr % MCCI_STM32L0_FLASH_HALF_PAGE_SIZE) != 0)
173 return false;
174
175 const uint32_t *pSrcData;
176 pSrcData = pSrc;
177
178 const size_t nHalfPage = MCCI_STM32L0_FLASH_HALF_PAGE_SIZE;
179
180 // wait
182 /* loop */;
183
184 // unlock
187
188 // unlock the PROG bit
191
192 result = true;
193 for (; nBytes > 0;
194 nBytes -= nHalfPage,
195 destAddr += nHalfPage,
196 pSrcData += nHalfPage / sizeof(uint32_t)
197 )
198 {
199 // we really don't want to take an interrupt while programming.
200 const uint32_t psw = McciArm_disableInterrupts();
201
202 result = McciBootloader_Stm32L0_programHalfPage(destAddr, pSrcData);
203
204 // reenable.
205 McciArm_setPRIMASK(psw);
206
207 if (! result)
208 break;
209 }
210
211 // lock
213 return result;
214 }
215
216/**** end of mccibootloader_stm32l0_systemflash.c ****/
static uint32_t McciArm_putRegOr(uint32_t reg, uint32_t orVal)
or 32-bit values to a cm0plus register
static uint32_t McciArm_getReg(uint32_t reg)
read a 32-bit value from a cm0plus register
static uint32_t McciArm_putReg(uint32_t reg, uint32_t val)
write a 32-bit value to a cm0plus register
static uint32_t McciArm_putRegClear(uint32_t reg, uint32_t clearVal)
clear out 32-bit values to a cm0plus register
McciBootloaderPlatform_SystemFlashEraseFn_t McciBootloader_Stm32L0_systemFlashErase
McciBootloaderPlatform_SystemFlashWriteFn_t McciBootloader_Stm32L0_systemFlashWrite
#define MCCI_STM32L0_REG_FLASH_PECR
Flash program and erase control register.
#define MCCI_STM32L0_REG_FLASH_PRGKEYR_UNLOCK2
unlock word 2 for PRGKEYR
#define MCCI_STM32L0_REG_FLASH_PEKEYR_UNLOCK2
unlock word 2 for PECR
#define MCCI_STM32L0_REG_FLASH_PECR_FPRG
Enable half-page programming mode.
#define MCCI_STM32L0_REG_FLASH_SR_EOP
End of program.
#define MCCI_STM32L0_REG_FLASH_PRGKEYR
Flash program/erase key register.
#define MCCI_STM32L0_REG_FLASH_PEKEYR
Flash PECR unlock key register.
#define MCCI_STM32L0_REG_FLASH_SR
Flash status register.
#define MCCI_STM32L0_REG_FLASH_PRGKEYR_UNLOCK1
unlock word 1 for PRGKEYR
#define MCCI_STM32L0_FLASH_HALF_PAGE_SIZE
size in bytes of a half-page
#define MCCI_STM32L0_REG_FLASH_PEKEYR_UNLOCK1
unlock word 1 for PECR
#define MCCI_STM32L0_REG_FLASH_PECR_PROG
Select program memory.
#define MCCI_STM32L0_REG_FLASH_SR_BSY
Busy doing write/erase.
#define MCCI_STM32L0_FLASH_PAGE_SIZE
size in bytes of a page
#define MCCI_STM32L0_REG_FLASH_PECR_ERASE
Erase operation requested/not requested.
#define MCCI_STM32L0_REG_FLASH_PECR_PELOCK
Lock the FLASH_PECR register.
bool McciBootloader_Stm32L0_programHalfPage(uint32_t flash_addr, const uint32_t *pData)