Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Modules / DiWheelDrive_1-1 / Boot / main.c @ fb5a5c5b

History | View | Annotate | Download (39.288 KB)

1
/************************************************************************************//**
2
* \file         Demo\ARMCM3_STM32_Olimex_STM32P103_GCC\Boot\main.c
3
* \brief        Bootloader application source file.
4
* \ingroup      Boot_ARMCM3_STM32_Olimex_STM32P103_GCC
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2012  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 "stm32f10x.h"                           /* microcontroller registers          */
39
#include "stm32f10x_conf.h"                      /* STM32 peripheral drivers           */
40
#include "timer.h"
41
#include "ARMCM3_STM32/types.h"
42
#include "AMiRo/amiroblt.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 LED_GPIO            GPIOA
51
#define LED_PIN             GPIO_Pin_1
52
#define DRIVE_PWM1A_GPIO    GPIOA
53
#define DRIVE_PWM1A_PIN     GPIO_Pin_2
54
#define DRIVE_PWM1B_GPIO    GPIOA
55
#define DRIVE_PWM1B_PIN     GPIO_Pin_3
56
#define MOTION_SCLK_GPIO    GPIOA
57
#define MOTION_SCLK_PIN     GPIO_Pin_5
58
#define MOTION_MISO_GPIO    GPIOA
59
#define MOTION_MISO_PIN     GPIO_Pin_6
60
#define MOTION_MOSI_GPIO    GPIOA
61
#define MOTION_MOSI_PIN     GPIO_Pin_7
62
#define PROG_RX_GPIO        GPIOA
63
#define PROG_RX_PIN         GPIO_Pin_9
64
#define PROG_TX_GPIO        GPIOA
65
#define PROG_TX_PIN         GPIO_Pin_10
66
#define CAN_RX_GPIO         GPIOA
67
#define CAN_RX_PIN          GPIO_Pin_11
68
#define CAN_TX_GPIO         GPIOA
69
#define CAN_TX_PIN          GPIO_Pin_12
70
#define SWDIO_GPIO          GPIOA
71
#define SWDIO_PIN           GPIO_Pin_13
72
#define SWCLK_GPIO          GPIOA
73
#define SWCLK_PIN           GPIO_Pin_14
74
#define DRIVE_PWM2B_GPIO    GPIOA
75
#define DRIVE_PWM2B_PIN     GPIO_Pin_15
76

    
77
#define DRIVE_SENSE2_GPIO   GPIOB
78
#define DRIVE_SENSE2_PIN    GPIO_Pin_1
79
#define POWER_EN_GPIO       GPIOB
80
#define POWER_EN_PIN        GPIO_Pin_2
81
#define DRIVE_PWM2A_GPIO    GPIOB
82
#define DRIVE_PWM2A_PIN     GPIO_Pin_3
83
#define COMPASS_DRDY_GPIO   GPIOB
84
#define COMPASS_DRDY_PIN    GPIO_Pin_5
85
#define DRIVE_ENC1A_GPIO    GPIOB
86
#define DRIVE_ENC1A_PIN     GPIO_Pin_6
87
#define DRIVE_ENC1B_GPIO    GPIOB
88
#define DRIVE_ENC1B_PIN     GPIO_Pin_7
89
#define COMPASS_SCL_GPIO    GPIOB
90
#define COMPASS_SCL_PIN     GPIO_Pin_8
91
#define COMPASS_SDA_GPIO    GPIOB
92
#define COMPASS_SDA_PIN     GPIO_Pin_9
93
#define IR_SCL_GPIO         GPIOB
94
#define IR_SCL_PIN          GPIO_Pin_10
95
#define IR_SDA_GPIO         GPIOB
96
#define IR_SDA_PIN          GPIO_Pin_11
97
#define IR_INT_GPIO         GPIOB
98
#define IR_INT_PIN          GPIO_Pin_12
99
#define GYRP_DRDY_GPIO      GPIOB
100
#define GYRO_DRDY_PIN       GPIO_Pin_13
101
#define SYS_UART_UP_GPIO    GPIOB
102
#define SYS_UART_UP_PIN     GPIO_Pin_14
103
#define ACCEL_INT_N_GPIO    GPIOB
104
#define ACCEL_INT_N_PIN     GPIO_Pin_15
105

    
106
#define DRIVE_SENSE1_GPIO   GPIOC
107
#define DRIVE_SENSE1_PIN    GPIO_Pin_0
108
#define SYS_SYNC_N_GPIO     GPIOC
109
#define SYS_SYNC_N_PIN      GPIO_Pin_1
110
#define PATH_DCSTAT_GPIO    GPIOC
111
#define PATH_DCSTAT_PIN     GPIO_Pin_3
112
#define PATH_DCEN_GPIO      GPIOC
113
#define PATH_DCEN_PIN       GPIO_Pin_5
114
#define DRIVE_ENC2B_GPIO    GPIOC
115
#define DRIVE_ENC2B_PIN     GPIO_Pin_6
116
#define DRIVE_ENC2A_GPIO    GPIOC
117
#define DRIVE_ENC2A_PIN     GPIO_Pin_7
118
#define SYS_PD_N_GPIO       GPIOC
119
#define SYS_PD_N_PIN        GPIO_Pin_8
120
#define SYS_REG_EN_GPIO     GPIOC
121
#define SYS_REG_EN_PIN      GPIO_Pin_9
122
#define SYS_UART_RX_GPIO    GPIOC
123
#define SYS_UART_RX_PIN     GPIO_Pin_10
124
#define SYS_UART_TX_GPIO    GPIOC
125
#define SYS_UART_TX_PIN     GPIO_Pin_11
126
#define ACCEL_SS_N_GPIO     GPIOC
127
#define ACCEL_SS_N_PIN      GPIO_Pin_13
128
#define GYRO_SS_N_GPIO      GPIOC
129
#define GYRO_SS_N_PIN       GPIO_Pin_14
130

    
131
#define OSC_IN_GPIO         GPIOD
132
#define OSC_IN_PIN          GPIO_Pin_0
133
#define OSC_OUT_GPIO        GPIOD
134
#define OSC_OUT_PIN         GPIO_Pin_1
135
#define SYS_WARMRST_N_GPIO  GPIOD
136
#define SYS_WARMRST_N_PIN   GPIO_Pin_2
137

    
138
#define RESET_TIMEOUT_MS    100
139

    
140
/****************************************************************************************
141
* Function prototypes
142
****************************************************************************************/
143
static void Init(void);
144

    
145
static void initGpio();
146
static void initExti();
147
void configGpioForShutdown();
148

    
149
ErrorStatus handleColdReset();
150
ErrorStatus handleUartWakeup();
151
ErrorStatus handleAccelWakeup();
152

    
153
ErrorStatus shutdownDisambiguationProcedure(const uint8_t type);
154
void shutdownToTransportation(const blt_bool exec_disambiguation);
155
void shutdownToDeepsleep(const blt_bool exec_disambiguation);
156
void shutdownToHibernate(const blt_bool exec_disambiguation);
157
void shutdownAndRestart(const blt_bool exec_disambiguation);
158

    
159
volatile blBackupRegister_t backup_reg;
160

    
161
/****************************************************************************************
162
* Callback configuration
163
****************************************************************************************/
164
void blCallbackShutdownTransportation(void);
165
void blCallbackShutdownDeepsleep(void);
166
void blCallbackShutdownHibernate(void);
167
void blCallbackShutdownRestart(void);
168
void blCallbackHandleShutdownRequest(void);
169

    
170
const blCallbackTable_t cbtable __attribute__ ((section ("_callback_table"))) = {
171
  .magicNumber = BL_MAGIC_NUMBER,
172
  .vBootloader = {BL_VERSION_ID_AMiRoBLT_Release, BL_VERSION_MAJOR, BL_VERSION_MINOR, 0},
173
  .vSSSP = {BL_VERSION_ID_SSSP, SSSP_VERSION_MAJOR, SSSP_VERSION_MINOR, 0},
174
  .vCompiler = {BL_VERSION_ID_GCC, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__},  // currently only GCC is supported
175
  .cbShutdownHibernate = blCallbackShutdownHibernate,
176
  .cbShutdownDeepsleep = blCallbackShutdownDeepsleep,
177
  .cbShutdownTransportation = blCallbackShutdownTransportation,
178
  .cbShutdownRestart = blCallbackShutdownRestart,
179
  .cbHandleShutdownRequest = blCallbackHandleShutdownRequest,
180
  .cb5 = (void*)0,
181
  .cb6 = (void*)0,
182
  .cb7 = (void*)0,
183
  .cb8 = (void*)0,
184
  .cb9 = (void*)0,
185
  .cb10 = (void*)0,
186
  .cb11 = (void*)0
187
};
188

    
189

    
190
/************************************************************************************//**
191
** \brief     This is the entry point for the bootloader application and is called
192
**            by the reset interrupt vector after the C-startup routines executed.
193
** \return    Program return code.
194
**
195
****************************************************************************************/
196
int main(void)
197
{
198
  /* initialize the microcontroller */
199
  Init();
200

    
201
  /* activate some required clocks */
202
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
203
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
204

    
205
  /* initialize GPIOs and EXTI lines */
206
  initGpio();
207
  setLed(BLT_TRUE);
208
  initExti();
209

    
210
  /* initialize the timer */
211
  TimerInit();
212

    
213
  /* detect the primary reason for this wakeup/restart */
214
  backup_reg.wakeup_pri_reason =
215
      ((RCC_GetFlagStatus(RCC_FLAG_LPWRRST) == SET) ? BL_WAKEUP_PRI_RSN_LPWRRST : 0) |
216
      ((RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET) ? BL_WAKEUP_PRI_RSN_WWDGRST : 0) |
217
      ((RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) ? BL_WAKEUP_PRI_RSN_IWDGRST : 0) |
218
      ((RCC_GetFlagStatus(RCC_FLAG_SFTRST) == SET) ? BL_WAKEUP_PRI_RSN_SFTRST : 0)   |
219
      ((RCC_GetFlagStatus(RCC_FLAG_PORRST) == SET) ? BL_WAKEUP_PRI_RSN_PORRST : 0)   |
220
      ((RCC_GetFlagStatus(RCC_FLAG_PINRST) == SET) ? BL_WAKEUP_PRI_RSN_PINRST : 0)   |
221
      ((PWR_GetFlagStatus(PWR_FLAG_WU) == SET) ? BL_WAKEUP_PRI_RSN_WKUP : 0);
222

    
223
  /* when woken from standby mode, detect the secondary reason for thiswakeup/reset */
224
  if ( (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_WKUP) && (PWR_GetFlagStatus(PWR_FLAG_SB) == SET) ) {
225
    if (GPIO_ReadInputDataBit(SYS_UART_UP_GPIO, SYS_UART_UP_PIN) == Bit_SET) {
226
      backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_UART;
227
    } else {
228
      backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_ACCEL;
229
    }
230
  } else {
231
    backup_reg.wakeup_sec_reason = BL_WAKEUP_SEC_RSN_UNKNOWN;
232
  }
233

    
234
  /* clear the flags */
235
  RCC_ClearFlag();
236
  PWR_ClearFlag(PWR_FLAG_WU);
237

    
238
  setLed(BLT_FALSE);
239

    
240
  /* wait 1ms for all signals to become stable */
241
  msleep(1);
242

    
243
  /* handle different wakeup/reset reasons */
244
  ErrorStatus status = ERROR;
245
  if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_WKUP) {
246
    /* the system was woken via WKUP pin */
247
    /* differenciate between two wakeup types */
248
    switch (backup_reg.wakeup_sec_reason) {
249
      case BL_WAKEUP_SEC_RSN_UART:
250
        status = handleUartWakeup();
251
        break;
252
      case BL_WAKEUP_SEC_RSN_ACCEL:
253
        status = handleAccelWakeup();
254
        break;
255
      default:
256
        status = ERROR;
257
        break;
258
    }
259
  } else if (backup_reg.wakeup_pri_reason & BL_WAKEUP_PRI_RSN_PINRST) {
260
    /* system was woken via NRST pin */
261
    status = handleColdReset();
262
  } else {
263
    /* system was woken/reset for an unexpected reason */
264
    blinkSOS(1);
265
    status = handleColdReset();
266
  }
267

    
268
  /* if something wehnt wrong, signal this failure */
269
  if (status != SUCCESS) {
270
    blinkSOSinf();
271
  }
272

    
273
  return 0;
274
} /*** end of main ***/
275

    
276

    
277
/************************************************************************************//**
278
** \brief     Initializes the microcontroller.
279
** \return    none.
280
**
281
****************************************************************************************/
282
static void Init(void)
283
{
284
  volatile blt_int32u StartUpCounter = 0, HSEStatus = 0;
285
  blt_int32u pll_multiplier;
286
#if (BOOT_FILE_LOGGING_ENABLE > 0) && (BOOT_COM_UART_ENABLE == 0)
287
  GPIO_InitTypeDef  GPIO_InitStruct;
288
  USART_InitTypeDef USART_InitStruct;
289
#endif
290

    
291
  /* reset the RCC clock configuration to the default reset state (for debug purpose) */
292
  /* set HSION bit */
293
  RCC->CR |= (blt_int32u)0x00000001;
294
  /* reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
295
  RCC->CFGR &= (blt_int32u)0xF8FF0000;
296
  /* reset HSEON, CSSON and PLLON bits */
297
  RCC->CR &= (blt_int32u)0xFEF6FFFF;
298
  /* reset HSEBYP bit */
299
  RCC->CR &= (blt_int32u)0xFFFBFFFF;
300
  /* reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
301
  RCC->CFGR &= (blt_int32u)0xFF80FFFF;
302
  /* disable all interrupts and clear pending bits  */
303
  RCC->CIR = 0x009F0000;
304
  /* enable HSE */
305
  RCC->CR |= ((blt_int32u)RCC_CR_HSEON);
306
  /* wait till HSE is ready and if Time out is reached exit */
307
  do
308
  {
309
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
310
    StartUpCounter++;
311
  }
312
  while((HSEStatus == 0) && (StartUpCounter != 1500));
313
  /* check if time out was reached */
314
  if ((RCC->CR & RCC_CR_HSERDY) == RESET)
315
  {
316
    /* cannot continue when HSE is not ready */
317
    ASSERT_RT(BLT_FALSE);
318
  }
319
  /* enable flash prefetch buffer */
320
  FLASH->ACR |= FLASH_ACR_PRFTBE;
321
  /* reset flash wait state configuration to default 0 wait states */
322
  FLASH->ACR &= (blt_int32u)((blt_int32u)~FLASH_ACR_LATENCY);
323
#if (BOOT_CPU_SYSTEM_SPEED_KHZ > 48000)
324
  /* configure 2 flash wait states */
325
  FLASH->ACR |= (blt_int32u)FLASH_ACR_LATENCY_2;
326
#elif (BOOT_CPU_SYSTEM_SPEED_KHZ > 24000)
327
  /* configure 1 flash wait states */
328
  FLASH->ACR |= (blt_int32u)FLASH_ACR_LATENCY_1;
329
#endif
330
  /* HCLK = SYSCLK */
331
  RCC->CFGR |= (blt_int32u)RCC_CFGR_HPRE_DIV1;
332
  /* PCLK2 = HCLK/2 */
333
  RCC->CFGR |= (blt_int32u)RCC_CFGR_PPRE2_DIV2;
334
  /* PCLK1 = HCLK/2 */
335
  RCC->CFGR |= (blt_int32u)RCC_CFGR_PPRE1_DIV2;
336
  /* reset PLL configuration */
337
  RCC->CFGR &= (blt_int32u)((blt_int32u)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | \
338
                                          RCC_CFGR_PLLMULL));
339
  /* assert that the pll_multiplier is between 2 and 16 */
340
  ASSERT_CT((BOOT_CPU_SYSTEM_SPEED_KHZ/BOOT_CPU_XTAL_SPEED_KHZ) >= 2);
341
  ASSERT_CT((BOOT_CPU_SYSTEM_SPEED_KHZ/BOOT_CPU_XTAL_SPEED_KHZ) <= 16);
342
  /* calculate multiplier value */
343
  pll_multiplier = BOOT_CPU_SYSTEM_SPEED_KHZ/BOOT_CPU_XTAL_SPEED_KHZ;
344
  /* convert to register value */
345
  pll_multiplier = (blt_int32u)((pll_multiplier - 2) << 18);
346
  /* set the PLL multiplier and clock source */
347
  RCC->CFGR |= (blt_int32u)(RCC_CFGR_PLLSRC_HSE | pll_multiplier);
348
  /* enable PLL */
349
  RCC->CR |= RCC_CR_PLLON;
350
  /* wait till PLL is ready */
351
  while((RCC->CR & RCC_CR_PLLRDY) == 0)
352