Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Demo / ARMCM4_STM32F405_Power_Management_GCC / Boot / main.c @ 69661903

History | View | Annotate | Download (60.7 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 "stm32f4xx.h"                           /* STM32 registers                    */
39
#include "stm32f4xx_conf.h"                      /* STM32 peripheral drivers           */
40
#include "com.h"
41
#include "ARMCM4_STM32/types.h"
42
#include "AMiRo/interfaces.h"
43
#include "AMiRo/helper.h"
44

    
45
/****************************************************************************************
46
* Defines
47
****************************************************************************************/
48
#define WKUP_GPIO               GPIOA
49
#define WKUP_PIN                GPIO_Pin_0
50
#define SYS_UART_TX_GPIO        GPIOA
51
#define SYS_UART_TX_PIN         GPIO_Pin_2
52
#define SYS_UART_RX_GPIO        GPIOA
53
#define SYS_UART_RX_PIN         GPIO_Pin_3
54
#define SYS_SPI_SS0_N_GPIO      GPIOA
55
#define SYS_SPI_SS0_N_PIN       GPIO_Pin_4
56
#define SYS_SPI_SCLK_GPIO       GPIOA
57
#define SYS_SPI_SCLK_PIN        GPIO_Pin_5
58
#define SYS_SPI_MISO_GPIO       GPIOA
59
#define SYS_SPI_MISO_PIN        GPIO_Pin_6
60
#define SYS_SPI_MOSI_GPIO       GPIOA
61
#define SYS_SPI_MOSI_PIN        GPIO_Pin_7
62
#define SYS_REG_EN_GPIO         GPIOA
63
#define SYS_REG_EN_PIN          GPIO_Pin_8
64
#define PROG_RX_GPIO            GPIOA
65
#define PROG_RX_PIN             GPIO_Pin_9
66
#define PROG_TX_GPIO            GPIOA
67
#define PROG_TX_PIN             GPIO_Pin_10
68
#define CAN_RX_GPIO             GPIOA
69
#define CAN_RX_PIN              GPIO_Pin_11
70
#define CAN_TX_GPIO             GPIOA
71
#define CAN_TX_PIN              GPIO_Pin_12
72
#define SWDIO_GPIO              GPIOA
73
#define SWDIO_PIN               GPIO_Pin_13
74
#define SWCLK_GPIO              GPIOA
75
#define SWCLK_PIN               GPIO_Pin_14
76
#define SYS_SPI_SS1_N_GPIO      GPIOA
77
#define SYS_SPI_SS1_N_PIN       GPIO_Pin_15
78

    
79
#define IR_INT1_N_GPIO          GPIOB
80
#define IR_INT1_N_PIN           GPIO_Pin_0
81
#define VSYS_SENSE_GPIO         GPIOB
82
#define VSYS_SENSE_PIN          GPIO_Pin_1
83
#define POWER_EN_GPIO           GPIOB
84
#define POWER_EN_PIN            GPIO_Pin_2
85
#define SYS_UART_DN_GPIO        GPIOB
86
#define SYS_UART_DN_PIN         GPIO_Pin_3
87
#define CHARGE_STAT2A_GPIO      GPIOB
88
#define CHARGE_STAT2A_PIN       GPIO_Pin_4
89
#define BUZZER_GPIO             GPIOB
90
#define BUZZER_PIN              GPIO_Pin_5
91
#define GAUGE_BATLOW2_GPIO      GPIOB
92
#define GAUGE_BATLOW2_PIN       GPIO_Pin_6
93
#define GAUGE_BATGD2_N_GPIO     GPIOB
94
#define GAUGE_BATGD2_N_PIN      GPIO_Pin_7
95
#define GAUGE_SCL2_GPIO         GPIOB
96
#define GAUGE_SCL2_PIN          GPIO_Pin_8
97
#define GAUGE_SDA2_GPIO         GPIOB
98
#define GAUGE_SDA2_PIN          GPIO_Pin_9
99
#define GAUGE_SCL1_GPIO         GPIOB
100
#define GAUGE_SCL1_PIN          GPIO_Pin_10
101
#define GAUGE_SDA1_GPIO         GPIOB
102
#define GAUGE_SDA1_PIN          GPIO_Pin_11
103
#define LED_GPIO                GPIOB
104
#define LED_PIN                 GPIO_Pin_12
105
#define BT_RTS_GPIO             GPIOB
106
#define BT_RTS_PIN              GPIO_Pin_13
107
#define BT_CTS_GPIO             GPIOB
108
#define BT_CTS_PIN              GPIO_Pin_14
109
#define SYS_UART_UP_GPIO        GPIOB
110
#define SYS_UART_UP_PIN         GPIO_Pin_15
111

    
112
#define CHARGE_STAT1A_GPIO      GPIOC
113
#define CHARGE_STAT1A_PIN       GPIO_Pin_0
114
#define GAUGE_BATLOW1_GPIO      GPIOC
115
#define GAUGE_BATLOW1_PIN       GPIO_Pin_1
116
#define GAUGE_BATGD1_N_GPIO     GPIOC
117
#define GAUGE_BATGD1_N_PIN      GPIO_Pin_2
118
#define CHARGE_EN1_N_GPIO       GPIOC
119
#define CHARGE_EN1_N_PIN        GPIO_Pin_3
120
#define IR_INT2_N_GPIO          GPIOC
121
#define IR_INT2_N_PIN           GPIO_Pin_4
122
#define TOUCH_INT_N_GPIO        GPIOC
123
#define TOUCH_INT_N_PIN         GPIO_Pin_5
124
#define SYS_DONE_GPIO           GPIOC
125
#define SYS_DONE_PIN            GPIO_Pin_6
126
#define SYS_PROG_N_GPIO         GPIOC
127
#define SYS_PROG_N_PIN          GPIO_Pin_7
128
#define PATH_DC_GPIO            GPIOC
129
#define PATH_DC_PIN             GPIO_Pin_8
130
#define SYS_SPI_DIR_GPIO        GPIOC
131
#define SYS_SPI_DIR_PIN         GPIO_Pin_9
132
#define BT_RX_GPIO              GPIOC
133
#define BT_RX_PIN               GPIO_Pin_10
134
#define BT_TX_GPIO              GPIOC
135
#define BT_TX_PIN               GPIO_Pin_11
136
#define SYS_SYNC_N_GPIO         GPIOC
137
#define SYS_SYNC_N_PIN          GPIO_Pin_12
138
#define SYS_PD_N_GPIO           GPIOC
139
#define SYS_PD_N_PIN            GPIO_Pin_13
140
#define SYS_WARMRST_N_GPIO      GPIOC
141
#define SYS_WARMRST_N_PIN       GPIO_Pin_14
142
#define BT_RST_GPIO             GPIOC
143
#define BT_RST_PIN              GPIO_Pin_15
144

    
145
#define OSC_IN_GPIO             GPIOD
146
#define OSC_IN_PIN              GPIO_Pin_0
147
#define OSC_OUT_GPIO            GPIOD
148
#define OSC_OUT_PIN             GPIO_Pin_1
149
#define CHARGE_EN2_N_GPIO       GPIOD
150
#define CHARGE_EN2_N_PIN        GPIO_Pin_2
151

    
152
#define HIBERNATE_TIME_MS       5000
153

    
154
/****************************************************************************************
155
* Function prototypes and static variables
156
****************************************************************************************/
157
static void Init(void);
158

    
159
static void initGpio();
160
static void initExti();
161
void configGpioForShutdown();
162
void systemPowerDown();
163

    
164
ErrorStatus handleColdReset();
165
ErrorStatus handleSoftwareReset();
166
ErrorStatus handleUartDnWakeup();
167
ErrorStatus handlePathDcWakeup();
168
ErrorStatus handleTouchWakeup();
169
ErrorStatus handleIwdgWakeup();
170

    
171
static void indicateHibernate();
172
static void AdcSingleMeasurement();
173

    
174
ADC_TypeDef* setupADC(ADC_TypeDef* adc, const uint16_t low_th, const uint16_t high_th);
175
uint16_t configIwdg(const uint16_t ms);
176

    
177
ErrorStatus shutdownDisambiguationProcedure(const uint8_t type);
178
void shutdownToTransportation();
179
void shutdownToDeepsleep();
180
void shutdownToHibernate();
181
void shutdownAndRestart();
182

    
183
volatile BlBackupRegister backup_reg;
184

    
185
/****************************************************************************************
186
* Callback configuration
187
****************************************************************************************/
188
void blCallbackShutdownTransportation(void);
189
void blCallbackShutdownDeepsleep(void);
190
void blCallbackShutdownHibernate(void);
191
void blCallbackShutdownRestart(void);
192
void blCallbackHandleShutdownRequest(void);
193

    
194
const BlCallbackTable cbtable __attribute__ ((section ("_callback_table"))) = {
195
  .magicNumber = BL_MAGIC_NUMBER,
196
  .versionMajor = BL_VERSION_MAJOR,
197
  .versionMinor = BL_VERSION_MINOR,
198
  .versionHotfix = 0,
199
  .cbShutdownHibernate = blCallbackShutdownHibernate,
200
  .cbShutdownDeepsleep = blCallbackShutdownDeepsleep,
201
  .cbShutdownTransportation = blCallbackShutdownTransportation,
202
  .cbShutdownRestart = blCallbackShutdownRestart,
203
  .cbHandleShutdownRequest = blCallbackHandleShutdownRequest,
204
  .cb5 = (void*)0,
205
  .cb6 = (void*)0,
206
  .cb7 = (void*)0,
207
  .cb8 = (void*)0,
208
  .cb9 = (void*)0,
209
  .cb10 = (void*)0,
210
  .cb11 = (void*)0
211
};
212

    
213
/************************************************************************************//**
214
** \brief     This is the entry point for the bootloader application and is called 
215
**            by the reset interrupt vector after the C-startup routines executed.
216
** \return    none.
217
**
218
****************************************************************************************/
219
void main(void)
220
{
221
  /* initialize the microcontroller */
222
  Init();
223

    
224
  /* activate some required clocks */
225
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
226
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
227
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
228

    
229
  /* initialize GPIOs and EXTI lines */
230
  initGpio();
231
  setLed(BLT_TRUE);
232
  initExti();
233

    
234
  /* initialize the timer */
235
  TimerInit(); // do not use saTimerInit() in order to initialize the static variable.
236

    
237
  /* read the backup register */
238
  backup_reg.raw = RTC_ReadBackupRegister(BL_RTC_BACKUP_REG);
239

    
240
  /* detect the primary reason for this wakeup/restart */
241
  backup_reg.wakeup_pri_reason =
242
      ((RCC_GetFlagStatus(RCC_FLAG_LPWRRST) == SET) ? BL_WAKEUP_PRI_RSN_LPWRRST : 0) |
243
      ((RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET) ? BL_WAKEUP_PRI_RSN_WWDGRST : 0) |
244
      ((RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) ? BL_WAKEUP_PRI_RSN_IWDGRST : 0) |
245
      ((RCC_GetFlagStatus(RCC_FLAG_SFTRST) == SET) ? BL_WAKEUP_PRI_RSN_SFTRST : 0)   |
246
      ((RCC_GetFlagStatus(RCC_FLAG_PORRST) == SET) ? BL_WAKEUP_PRI_RSN_PORRST : 0)   |
247
      ((RCC_GetFlagStatus(RCC_FLAG_PINRST) == SET) ? BL_WAKEUP_PRI_RSN_PINRST : 0)   |
248
      ((RCC_GetFlagStatus(RCC_FLAG_BORRST) == SET) ? BL_WAKEUP_PRI_RSN_BORRST : 0)   |
249
      ((PWR_GetFlagStatus(PWR_FLAG_WU) == SET) ? BL_WAKEUP_PRI_RSN_WKUP : 0);
250

    
251
  /* when woken from standby mode, detect the secondary reason for this wakeup/reset */
252
  if ( (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_WKUP) && (PWR_GetFlagStatus(PWR_FLAG_SB) == SET) ) {
253
    if (GPIO_ReadInputDataBit(SYS_UART_DN_GPIO, SYS_UART_DN_PIN) == Bit_RESET) {
254
      backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_UART;
255
    } else if (GPIO_ReadInputDataBit(PATH_DC_GPIO, PATH_DC_PIN) == Bit_SET) {
256
      backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_PWRPLUG;
257
    } else {
258
      backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_TOUCH;
259
    }
260
  } else {
261
    backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_UNKNOWN;
262
  }
263

    
264
  /* store the information about this wakeup/restart in the backup register */
265
  PWR_BackupAccessCmd(ENABLE);
266
  RTC_WriteBackupRegister(BL_RTC_BACKUP_REG, backup_reg.raw);
267

    
268
  /* clear the flags */
269
  RCC_ClearFlag();
270
  PWR_ClearFlag(PWR_FLAG_WU);
271

    
272
  setLed(BLT_FALSE);
273

    
274
  /* handle different wakeup/reset reasons */
275
  ErrorStatus status = ERROR;
276
  if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_SFTRST) {
277
    /* system was reset by software */
278
    status = handleSoftwareReset();
279
  } else if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_WKUP) {
280
    /* system was woken via WKUP pin */
281
    /* differeciate between thre wakeup types */
282
    switch (backup_reg.wakeup_sec_reason) {
283
      case BL_WAKEUP_SEC_RSN_UART:
284
        status = handleUartDnWakeup();
285
        break;
286
      case BL_WAKEUP_SEC_RSN_PWRPLUG:
287
        status = handlePathDcWakeup();
288
        break;
289
      case BL_WAKEUP_SEC_RSN_TOUCH:
290
        status = handleTouchWakeup();
291
        break;
292
      default:
293
        status = ERROR;
294
        break;
295
    }
296
  } else if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_IWDGRST) {
297
    /* system was woken by IWDG */
298
    status = handleIwdgWakeup();
299
  } else if (backup_reg.wakeup_pri_reason == BL_WAKEUP_PRI_RSN_PINRST) {
300
    /* system was reset via NRST pin */
301
    status = handleColdReset();
302
  } else {
303
    /* system was woken/reset for an unexpected reason.
304
     * In this case the LED blinks "SOS" (... --- ...) and the system resets.
305
     */
306
    blinkSOS(1);
307
    status = ERROR;
308
    backup_reg.shutdown_pri_reason = BL_SHUTDOWN_PRI_RSN_RESTART;
309
    backup_reg.shutdown_sec_reason = BL_SHUTDOWN_SEC_RSN_UNKNOWN;
310
    RTC_WriteBackupRegister(BL_RTC_BACKUP_REG, backup_reg.raw);
311
    NVIC_SystemReset();
312
  }
313

    
314
  /* if something went wrong, signal this failure */
315
  if (status != SUCCESS) {
316
    blinkSOSinf();
317
  }
318

    
319
  return;
320
} /*** end of main ***/
321

    
322

    
323
/************************************************************************************//**
324
** \brief     Initializes the microcontroller. 
325
** \return    none.
326
**
327
****************************************************************************************/
328
static void Init(void)
329
{
330
#if (BOOT_COM_UART_ENABLE > 0 || BOOT_GATE_UART_ENABLE > 0)
331
  GPIO_InitTypeDef  GPIO_InitStructure;
332
#elif (BOOT_FILE_SYS_ENABLE > 0)
333
  GPIO_InitTypeDef  GPIO_InitStructure;
334
  USART_InitTypeDef USART_InitStructure;
335
#elif (BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0)
336
  GPIO_InitTypeDef  GPIO_InitStructure;
337
#endif  
338

    
339
  /* initialize the system and its clocks */
340
  SystemInit();
341
#if (BOOT_COM_UART_ENABLE > 0 || BOOT_GATE_UART_ENABLE > 0)
342
  /* enable UART peripheral clock */
343
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
344
  /* enable GPIO peripheral clock for transmitter and receiver pins */
345
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
346
  /* connect the pin to the peripherals alternate function */
347
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
348
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
349