amiro-blt / Target / Modules / PowerManagement_1-2 / Boot / main.c @ 2b9a14a2
History | View | Annotate | Download (57.492 KB)
1 |
/************************************************************************************//** |
---|---|
2 |
* \file Demo\ARMCM4_STM32_Olimex_STM32E407_GCC\Boot\main.c
|
3 |
* \brief Bootloader application source file.
|
4 |
* \ingroup Boot_ARMCM4_STM32_Olimex_STM32E407_GCC
|
5 |
* \internal
|
6 |
*----------------------------------------------------------------------------------------
|
7 |
* C O P Y R I G H T
|
8 |
*----------------------------------------------------------------------------------------
|
9 |
* Copyright (c) 2013 by Feaser http://www.feaser.com All rights reserved
|
10 |
*
|
11 |
*----------------------------------------------------------------------------------------
|
12 |
* L I C E N S E
|
13 |
*----------------------------------------------------------------------------------------
|
14 |
* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
15 |
* modify it under the terms of the GNU General Public License as published by the Free
|
16 |
* Software Foundation, either version 3 of the License, or (at your option) any later
|
17 |
* version.
|
18 |
*
|
19 |
* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
20 |
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
21 |
* PURPOSE. See the GNU General Public License for more details.
|
22 |
*
|
23 |
* You should have received a copy of the GNU General Public License along with OpenBLT.
|
24 |
* If not, see <http://www.gnu.org/licenses/>.
|
25 |
*
|
26 |
* A special exception to the GPL is included to allow you to distribute a combined work
|
27 |
* that includes OpenBLT without being obliged to provide the source code for any
|
28 |
* proprietary components. The exception text is included at the bottom of the license
|
29 |
* file <license.html>.
|
30 |
*
|
31 |
* \endinternal
|
32 |
****************************************************************************************/
|
33 |
|
34 |
/****************************************************************************************
|
35 |
* Include files
|
36 |
****************************************************************************************/
|
37 |
#include "boot.h" /* bootloader generic header */ |
38 |
#include "com.h" |
39 |
#include "ARMCM4_STM32/types.h" |
40 |
#include "AMiRo/amiroblt.h" |
41 |
#include "helper.h" |
42 |
#include "iodef.h" |
43 |
|
44 |
/****************************************************************************************
|
45 |
* Defines
|
46 |
****************************************************************************************/
|
47 |
#define HIBERNATE_TIME_MS 5000 |
48 |
|
49 |
/****************************************************************************************
|
50 |
* Function prototypes and static variables
|
51 |
****************************************************************************************/
|
52 |
static void Init(void); |
53 |
|
54 |
static void initGpio(void); |
55 |
static void initExti(void); |
56 |
void configGpioForShutdown(void); |
57 |
void systemPowerDown(void); |
58 |
|
59 |
ErrorStatus handleColdReset(void);
|
60 |
ErrorStatus handleSoftwareReset(void);
|
61 |
ErrorStatus handleUartDnWakeup(void);
|
62 |
ErrorStatus handlePathDcWakeup(void);
|
63 |
ErrorStatus handleTouchWakeup(void);
|
64 |
ErrorStatus handleIwdgWakeup(void);
|
65 |
|
66 |
static void indicateHibernate(void); |
67 |
static void AdcSingleMeasurement(void); |
68 |
|
69 |
ADC_TypeDef* setupADC(ADC_TypeDef* adc, const uint16_t low_th, const uint16_t high_th); |
70 |
uint16_t configIwdg(const uint16_t ms);
|
71 |
|
72 |
ErrorStatus shutdownDisambiguationProcedure(const uint8_t type);
|
73 |
void shutdownToTransportation(void); |
74 |
void shutdownToDeepsleep(void); |
75 |
void shutdownToHibernate(void); |
76 |
void shutdownAndRestart(void); |
77 |
|
78 |
volatile blBackupRegister_t backup_reg;
|
79 |
|
80 |
/****************************************************************************************
|
81 |
* Callback configuration
|
82 |
****************************************************************************************/
|
83 |
void blCallbackShutdownTransportation(void); |
84 |
void blCallbackShutdownDeepsleep(void); |
85 |
void blCallbackShutdownHibernate(void); |
86 |
void blCallbackShutdownRestart(void); |
87 |
void blCallbackHandleShutdownRequest(void); |
88 |
|
89 |
const blCallbackTable_t cbtable __attribute__ ((section ("_callback_table"))) = { |
90 |
.magicNumber = BL_MAGIC_NUMBER, |
91 |
.vBootloader = {BL_VERSION_ID_AMiRoBLT_Beta, BL_VERSION_MAJOR, BL_VERSION_MINOR, 4},
|
92 |
.vSSSP = {BL_VERSION_ID_SSSP, BL_SSSP_VERSION_MAJOR, BL_SSSP_VERSION_MINOR, 0},
|
93 |
.vCompiler = {BL_VERSION_ID_GCC, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__}, // currently only GCC is supported
|
94 |
.cbShutdownHibernate = blCallbackShutdownHibernate, |
95 |
.cbShutdownDeepsleep = blCallbackShutdownDeepsleep, |
96 |
.cbShutdownTransportation = blCallbackShutdownTransportation, |
97 |
.cbShutdownRestart = blCallbackShutdownRestart, |
98 |
.cbHandleShutdownRequest = blCallbackHandleShutdownRequest, |
99 |
.cb5 = (void*)0, |
100 |
.cb6 = (void*)0, |
101 |
.cb7 = (void*)0, |
102 |
.cb8 = (void*)0, |
103 |
.cb9 = (void*)0, |
104 |
.cb10 = (void*)0, |
105 |
.cb11 = (void*)0 |
106 |
}; |
107 |
|
108 |
/************************************************************************************//** |
109 |
** \brief This is the entry point for the bootloader application and is called
|
110 |
** by the reset interrupt vector after the C-startup routines executed.
|
111 |
** \return none.
|
112 |
**
|
113 |
****************************************************************************************/
|
114 |
void main(void) |
115 |
{ |
116 |
/* initialize the microcontroller */
|
117 |
Init(); |
118 |
|
119 |
/* activate some required clocks */
|
120 |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE); |
121 |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); |
122 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); |
123 |
|
124 |
/* initialize GPIOs and EXTI lines */
|
125 |
initGpio(); |
126 |
setLed(BLT_TRUE); |
127 |
initExti(); |
128 |
|
129 |
/* initialize the timer */
|
130 |
TimerInit(); // do not use saTimerInit() in order to initialize the static variable.
|
131 |
|
132 |
/* read the backup register */
|
133 |
backup_reg.raw = RTC_ReadBackupRegister(BL_RTC_BACKUP_REG); |
134 |
|
135 |
/* detect the primary reason for this wakeup/restart */
|
136 |
backup_reg.wakeup_pri_reason = |
137 |
((RCC_GetFlagStatus(RCC_FLAG_LPWRRST) == SET) ? BL_WAKEUP_PRI_RSN_LPWRRST : 0) |
|
138 |
((RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET) ? BL_WAKEUP_PRI_RSN_WWDGRST : 0) |
|
139 |
((RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) ? BL_WAKEUP_PRI_RSN_IWDGRST : 0) |
|
140 |
((RCC_GetFlagStatus(RCC_FLAG_SFTRST) == SET) ? BL_WAKEUP_PRI_RSN_SFTRST : 0) |
|
141 |
((RCC_GetFlagStatus(RCC_FLAG_PORRST) == SET) ? BL_WAKEUP_PRI_RSN_PORRST : 0) |
|
142 |
((RCC_GetFlagStatus(RCC_FLAG_PINRST) == SET) ? BL_WAKEUP_PRI_RSN_PINRST : 0) |
|
143 |
((RCC_GetFlagStatus(RCC_FLAG_BORRST) == SET) ? BL_WAKEUP_PRI_RSN_BORRST : 0) |
|
144 |
((PWR_GetFlagStatus(PWR_FLAG_WU) == SET) ? BL_WAKEUP_PRI_RSN_WKUP : 0);
|
145 |
|
146 |
/* when woken from standby mode, detect the secondary reason for this wakeup/reset */
|
147 |
if ( (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_WKUP) && (PWR_GetFlagStatus(PWR_FLAG_SB) == SET) ) {
|
148 |
if (GPIO_ReadInputDataBit(SYS_UART_DN_GPIO, SYS_UART_DN_PIN) == Bit_RESET) {
|
149 |
backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_UART; |
150 |
} else if (GPIO_ReadInputDataBit(PATH_DC_GPIO, PATH_DC_PIN) == Bit_SET) { |
151 |
backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_PWRPLUG; |
152 |
} else {
|
153 |
backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_TOUCH; |
154 |
} |
155 |
} else {
|
156 |
backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_UNKNOWN; |
157 |
} |
158 |
|
159 |
/* store the information about this wakeup/restart in the backup register */
|
160 |
PWR_BackupAccessCmd(ENABLE); |
161 |
RTC_WriteBackupRegister(BL_RTC_BACKUP_REG, backup_reg.raw); |
162 |
|
163 |
/* clear the flags */
|
164 |
RCC_ClearFlag(); |
165 |
PWR_ClearFlag(PWR_FLAG_WU); |
166 |
|
167 |
setLed(BLT_FALSE); |
168 |
|
169 |
/*
|
170 |
* Measure the current voltage of VSYS and enable the chargers if it was found to be > 9V.
|
171 |
*/
|
172 |
AdcSingleMeasurement(); |
173 |
if ( (((float)(ADC_GetConversionValue(ADC1)) / (float)0x0FFF) * 3.3f * 5.33f) > 9.0f ) { |
174 |
/* VSYS was found to be > 9V */
|
175 |
setLed(BLT_TRUE); |
176 |
GPIO_ResetBits(CHARGE_EN1_N_GPIO, CHARGE_EN1_N_PIN); |
177 |
GPIO_ResetBits(CHARGE_EN2_N_GPIO, CHARGE_EN2_N_PIN); |
178 |
} |
179 |
|
180 |
/* handle different wakeup/reset reasons */
|
181 |
ErrorStatus status = ERROR; |
182 |
if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_SFTRST) {
|
183 |
/* system was reset by software */
|
184 |
status = handleSoftwareReset(); |
185 |
} else if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_WKUP) { |
186 |
/* system was woken via WKUP pin */
|
187 |
/* differeciate between thre wakeup types */
|
188 |
switch (backup_reg.wakeup_sec_reason) {
|
189 |
case BL_WAKEUP_SEC_RSN_UART:
|
190 |
status = handleUartDnWakeup(); |
191 |
break;
|
192 |
case BL_WAKEUP_SEC_RSN_PWRPLUG:
|
193 |
status = handlePathDcWakeup(); |
194 |
break;
|
195 |
case BL_WAKEUP_SEC_RSN_TOUCH:
|
196 |
status = handleTouchWakeup(); |
197 |
break;
|
198 |
default:
|
199 |
status = ERROR; |
200 |
break;
|
201 |
} |
202 |
} else if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_IWDGRST) { |
203 |
/* system was woken by IWDG */
|
204 |
status = handleIwdgWakeup(); |
205 |
} else if (backup_reg.wakeup_pri_reason == BL_WAKEUP_PRI_RSN_PINRST) { |
206 |
/* system was reset via NRST pin */
|
207 |
status = handleColdReset(); |
208 |
} else {
|
209 |
/* system was woken/reset for an unexpected reason.
|
210 |
* In this case the LED blinks "SOS" (... --- ...) and the system resets.
|
211 |
*/
|
212 |
blinkSOS(1);
|
213 |
status = ERROR; |
214 |
backup_reg.shutdown_pri_reason = BL_SHUTDOWN_PRI_RSN_RESTART; |
215 |
backup_reg.shutdown_sec_reason = BL_SHUTDOWN_SEC_RSN_UNKNOWN; |
216 |
RTC_WriteBackupRegister(BL_RTC_BACKUP_REG, backup_reg.raw); |
217 |
NVIC_SystemReset(); |
218 |
} |
219 |
|
220 |
/* if something went wrong, signal this failure */
|
221 |
if (status != SUCCESS) {
|
222 |
blinkSOSinf(); |
223 |
} |
224 |
|
225 |
return;
|
226 |
} /*** end of main ***/
|
227 |
|
228 |
|
229 |
/************************************************************************************//** |
230 |
** \brief Initializes the microcontroller.
|
231 |
** \return none.
|
232 |
**
|
233 |
****************************************************************************************/
|
234 |
static void Init(void) |
235 |
{ |
236 |
#if (BOOT_COM_UART_ENABLE > 0 || BOOT_GATE_UART_ENABLE > 0) |
237 |
GPIO_InitTypeDef GPIO_InitStructure; |
238 |
#elif (BOOT_FILE_SYS_ENABLE > 0) |
239 |
GPIO_InitTypeDef GPIO_InitStructure; |
240 |
USART_InitTypeDef USART_InitStructure; |
241 |
#elif (BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0) |
242 |
GPIO_InitTypeDef GPIO_InitStructure; |
243 |
#endif
|
244 |
|
245 |
/* initialize the system and its clocks */
|
246 |
SystemInit(); |
247 |
#if (BOOT_COM_UART_ENABLE > 0 || BOOT_GATE_UART_ENABLE > 0) |
248 |
/* enable UART peripheral clock */
|
249 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); |
250 |
/* enable GPIO peripheral clock for transmitter and receiver pins */
|
251 |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); |
252 |
/* connect the pin to the peripherals alternate function */
|
253 |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); |
254 |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); |
255 |
/* configure USART Tx as alternate function */
|
256 |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
257 |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; |
258 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
259 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; |
260 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
261 |
GPIO_Init(GPIOA, &GPIO_InitStructure); |
262 |
/* configure USART Rx as alternate function */
|
263 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
264 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; |
265 |
GPIO_Init(GPIOA, &GPIO_InitStructure); |
266 |
#endif
|
267 |
|
268 |
#if (BOOT_COM_BLUETOOTH_UART_ENABLE > 0) |
269 |
/* enable UART peripheral clock */
|
270 |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); |
271 |
|
272 |
/* enable GPIO peripheral clock for transmitter and receiver pins */
|
273 |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); |
274 |
/* connect the pin to the peripherals alternate function */
|
275 |
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3); |
276 |
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3); |
277 |
/* configure USART Tx as alternate function */
|
278 |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
279 |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; |
280 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
281 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; |
282 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
283 |
GPIO_Init(GPIOC, &GPIO_InitStructure); |
284 |
/* configure USART Rx as alternate function */
|
285 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
286 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; |
287 |
GPIO_Init(GPIOC, &GPIO_InitStructure); |
288 |
|
289 |
/* Configure Bluetooth reset pin */
|
290 |
GPIO_InitTypeDef gpio_init; |
291 |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); |
292 |
gpio_init.GPIO_Pin = BT_RST_PIN; |
293 |
gpio_init.GPIO_OType = GPIO_OType_OD; |
294 |
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; |
295 |
gpio_init.GPIO_Mode = GPIO_Mode_OUT; |
296 |
gpio_init.GPIO_Speed = GPIO_Speed_50MHz; |
297 |
GPIO_Init(BT_RST_GPIO, &gpio_init); |
298 |
/* Reset Bluetooth reset pin */
|
299 |
GPIO_ResetBits(BT_RST_GPIO, BT_RST_PIN); |
300 |
#endif
|
301 |
|
302 |
|
303 |
#if (BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0) |
304 |
/* enable clocks for CAN transmitter and receiver pins */
|
305 |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); |
306 |
/* select alternate function for the CAN pins */
|
307 |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1); |
308 |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1); |
309 |
/* configure CAN RX and TX pins */
|
310 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; |
311 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
312 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
313 |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
314 |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
315 |
GPIO_Init(GPIOA, &GPIO_InitStructure); |
316 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; |
317 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
318 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
319 |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
320 |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
321 |
GPIO_Init(GPIOA, &GPIO_InitStructure); |
322 |
#endif
|
323 |
} /*** end of Init ***/
|
324 |
|
325 |
/*
|
326 |
* Initializes all GPIO used by the bootloader
|
327 |
*/
|
328 |
static void initGpio(void) { |
329 |
GPIO_InitTypeDef gpio_init; |
330 |
|
331 |
/*
|
332 |
* OUTPUTS
|
333 |
*/
|
334 |
|
335 |
/* initialize LED and push it up (inactive) */
|
336 |
GPIO_SetBits(LED_GPIO, LED_PIN); |
337 |
gpio_init.GPIO_Pin = LED_PIN; |
338 |
gpio_init.GPIO_Mode = GPIO_Mode_OUT; |
339 |
gpio_init.GPIO_Speed = GPIO_Speed_50MHz; |
340 |
gpio_init.GPIO_OType = GPIO_OType_PP; |
341 |
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; |
342 |
GPIO_Init(LED_GPIO, &gpio_init); |
343 |
|
344 |
/* initialize SYS_PD_N and push it up (inactive) */
|
345 |
GPIO_SetBits(SYS_PD_N_GPIO, SYS_PD_N_PIN); |
346 |
gpio_init.GPIO_Pin = SYS_PD_N_PIN; |
347 |
gpio_init.GPIO_Mode = GPIO_Mode_OUT; |
348 |
gpio_init.GPIO_Speed = GPIO_Speed_50MHz; |
349 |
gpio_init.GPIO_OType = GPIO_OType_OD; |
350 |
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; |
351 |
GPIO_Init(SYS_PD_N_GPIO, &gpio_init); |
352 |
|
353 |
/* initialize SYS_SYNC_N and pull it down (active) */
|
354 |
GPIO_ResetBits(SYS_SYNC_N_GPIO, SYS_SYNC_N_PIN); |
355 |
gpio_init.GPIO_Pin = SYS_SYNC_N_PIN; |
356 |
gpio_init.GPIO_Mode = GPIO_Mode_OUT; |
357 |
gpio_init.GPIO_Speed = GPIO_Speed_50MHz; |
358 |
gpio_init.GPIO_OType = GPIO_OType_OD; |
359 |
gpio_init.GPIO_ |