LP-602 significant change to USB layer. force complete USB stack reset on replug...
[librepilot.git] / flight / pios / stm32f4xx / pios_bl_helper.c
blob8b215045074f5a600710f716bcd9d2b1a0594711
1 /**
2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
4 * @{
5 * @addtogroup PIOS_BOOTLOADER Functions
6 * @brief HAL code to interface to the OpenPilot AHRS module
7 * @{
9 * @file pios_bl_helper.c
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
11 * @brief Bootloader Helper Functions
12 * @see The GNU Public License (GPL) Version 3
14 *****************************************************************************/
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <pios.h>
33 #ifdef PIOS_INCLUDE_BL_HELPER
35 #include <pios_board_info.h>
36 #include <stm32f4xx_flash.h>
37 #include <stdbool.h>
39 uint8_t *PIOS_BL_HELPER_FLASH_If_Read(uint32_t SectorAddress)
41 return (uint8_t *)(SectorAddress);
44 #if defined(PIOS_INCLUDE_BL_HELPER_WRITE_SUPPORT)
46 static bool erase_flash(uint32_t startAddress, uint32_t endAddress);
48 uint8_t PIOS_BL_HELPER_FLASH_Ini()
50 FLASH_Unlock();
51 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
52 return 1;
55 struct device_flash_sector {
56 uint32_t start;
57 uint32_t size;
58 uint16_t st_sector;
61 static struct device_flash_sector flash_sectors[] = {
62 [0] = {
63 .start = 0x08000000,
64 .size = 16 * 1024,
65 .st_sector = FLASH_Sector_0,
67 [1] = {
68 .start = 0x08004000,
69 .size = 16 * 1024,
70 .st_sector = FLASH_Sector_1,
72 [2] = {
73 .start = 0x08008000,
74 .size = 16 * 1024,
75 .st_sector = FLASH_Sector_2,
77 [3] = {
78 .start = 0x0800C000,
79 .size = 16 * 1024,
80 .st_sector = FLASH_Sector_3,
82 [4] = {
83 .start = 0x08010000,
84 .size = 64 * 1024,
85 .st_sector = FLASH_Sector_4,
87 [5] = {
88 .start = 0x08020000,
89 .size = 128 * 1024,
90 .st_sector = FLASH_Sector_5,
92 [6] = {
93 .start = 0x08040000,
94 .size = 128 * 1024,
95 .st_sector = FLASH_Sector_6,
97 [7] = {
98 .start = 0x08060000,
99 .size = 128 * 1024,
100 .st_sector = FLASH_Sector_7,
102 [8] = {
103 .start = 0x08080000,
104 .size = 128 * 1024,
105 .st_sector = FLASH_Sector_8,
107 [9] = {
108 .start = 0x080A0000,
109 .size = 128 * 1024,
110 .st_sector = FLASH_Sector_9,
112 [10] = {
113 .start = 0x080C0000,
114 .size = 128 * 1024,
115 .st_sector = FLASH_Sector_10,
117 [11] = {
118 .start = 0x080E0000,
119 .size = 128 * 1024,
120 .st_sector = FLASH_Sector_11,
122 [12] = {
123 .start = 0x08100000,
124 .size = 16 * 1024,
125 .st_sector = FLASH_Sector_12,
127 [13] = {
128 .start = 0x08104000,
129 .size = 16 * 1024,
130 .st_sector = FLASH_Sector_13,
132 [14] = {
133 .start = 0x08108000,
134 .size = 16 * 1024,
135 .st_sector = FLASH_Sector_14,
137 [15] = {
138 .start = 0x0810C000,
139 .size = 16 * 1024,
140 .st_sector = FLASH_Sector_15,
142 [16] = {
143 .start = 0x08110000,
144 .size = 64 * 1024,
145 .st_sector = FLASH_Sector_16,
147 [17] = {
148 .start = 0x08120000,
149 .size = 128 * 1024,
150 .st_sector = FLASH_Sector_17,
152 [18] = {
153 .start = 0x08140000,
154 .size = 128 * 1024,
155 .st_sector = FLASH_Sector_18,
157 [19] = {
158 .start = 0x08160000,
159 .size = 128 * 1024,
160 .st_sector = FLASH_Sector_19,
162 [20] = {
163 .start = 0x08180000,
164 .size = 128 * 1024,
165 .st_sector = FLASH_Sector_20,
167 [21] = {
168 .start = 0x081A0000,
169 .size = 128 * 1024,
170 .st_sector = FLASH_Sector_21,
172 [22] = {
173 .start = 0x081C0000,
174 .size = 128 * 1024,
175 .st_sector = FLASH_Sector_22,
177 [23] = {
178 .start = 0x081E0000,
179 .size = 128 * 1024,
180 .st_sector = FLASH_Sector_23,
184 static bool PIOS_BL_HELPER_FLASH_GetSectorInfo(uint32_t address, uint8_t *sector_number, uint32_t *sector_start, uint32_t *sector_size)
186 for (uint8_t i = 0; i < NELEMENTS(flash_sectors); i++) {
187 struct device_flash_sector *sector = &flash_sectors[i];
188 if ((address >= sector->start) &&
189 (address < (sector->start + sector->size))) {
190 /* address lies within this sector */
191 *sector_number = sector->st_sector;
192 *sector_start = sector->start;
193 *sector_size = sector->size;
194 return true;
198 return false;
201 uint8_t PIOS_BL_HELPER_FLASH_Start()
203 const struct pios_board_info *bdinfo = &pios_board_info_blob;
204 uint32_t startAddress = bdinfo->fw_base;
205 uint32_t endAddress = bdinfo->fw_base + bdinfo->fw_size + bdinfo->desc_size;
207 bool success = erase_flash(startAddress, endAddress);
209 return (success) ? 1 : 0;
213 uint8_t PIOS_BL_HELPER_FLASH_Erase_Bootloader()
215 /// Bootloader memory space erase
216 uint32_t startAddress = BL_BANK_BASE;
217 uint32_t endAddress = BL_BANK_BASE + BL_BANK_SIZE;
219 bool success = erase_flash(startAddress, endAddress);
221 return (success) ? 1 : 0;
224 static bool erase_flash(uint32_t startAddress, uint32_t endAddress)
226 uint32_t pageAddress = startAddress;
227 bool fail = false;
229 while ((pageAddress < endAddress) && (fail == false)) {
230 uint8_t sector_number;
231 uint32_t sector_start;
232 uint32_t sector_size;
233 if (!PIOS_BL_HELPER_FLASH_GetSectorInfo(pageAddress,
234 &sector_number,
235 &sector_start,
236 &sector_size)) {
237 /* We're asking for an invalid flash address */
238 PIOS_Assert(0);
240 for (int retry = 0; retry < MAX_DEL_RETRYS; ++retry) {
241 // if erasing area contain whole bank2 area, using bank erase
242 // bank2: sector 12 to sector 23
243 if (sector_start == flash_sectors[12].start &&
244 endAddress >= (flash_sectors[23].start + flash_sectors[23].size)) {
245 if (FLASH_EraseAllBank2Sectors(VoltageRange_3) == FLASH_COMPLETE) {
246 fail = false;
247 // using bank2 total size substitute sector_size
248 sector_size = flash_sectors[23].start - flash_sectors[12].start + flash_sectors[23].size;
249 break;
250 } else {
251 fail = true;
253 } else if (FLASH_EraseSector(sector_number, VoltageRange_3) == FLASH_COMPLETE) {
254 fail = false;
255 break;
256 } else {
257 fail = true;
260 /* Move to the next sector */
261 pageAddress += sector_size;
263 return !fail;
266 #endif /* if defined(PIOS_INCLUDE_BL_HELPER_WRITE_SUPPORT) */
268 uint32_t PIOS_BL_HELPER_CRC_Memory_Calc()
270 const struct pios_board_info *bdinfo = &pios_board_info_blob;
272 PIOS_BL_HELPER_CRC_Ini();
273 CRC_ResetDR();
274 CRC_CalcBlockCRC((uint32_t *)bdinfo->fw_base, (bdinfo->fw_size) >> 2);
275 return CRC_GetCRC();
278 void PIOS_BL_HELPER_FLASH_Read_Description(uint8_t *array, uint8_t size)
280 const struct pios_board_info *bdinfo = &pios_board_info_blob;
281 uint8_t x = 0;
283 if (size > bdinfo->desc_size) {
284 size = bdinfo->desc_size;
286 for (uint32_t i = bdinfo->fw_base + bdinfo->fw_size; i < bdinfo->fw_base + bdinfo->fw_size + size; ++i) {
287 array[x] = *PIOS_BL_HELPER_FLASH_If_Read(i);
288 ++x;
292 void PIOS_BL_HELPER_CRC_Ini()
295 #endif /* PIOS_INCLUDE_BL_HELPER */