Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Demo / ARMCM3_STM32F103_DiWheelDrive_GCC / Boot / main.c @ 6feb42c8

History | View | Annotate | Download (39.265 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
/****************************************************************************************
47
* Defines
48
****************************************************************************************/
49
#define WKUP_GPIO           GPIOA
50
#define WKUP_PIN            GPIO_Pin_0
51
#define LED_GPIO            GPIOA
52
#define LED_PIN             GPIO_Pin_1
53
#define DRIVE_PWM1A_GPIO    GPIOA
54
#define DRIVE_PWM1A_PIN     GPIO_Pin_2
55
#define DRIVE_PWM1B_GPIO    GPIOA
56
#define DRIVE_PWM1B_PIN     GPIO_Pin_3
57
#define MOTION_SCLK_GPIO    GPIOA
58
#define MOTION_SCLK_PIN     GPIO_Pin_5
59
#define MOTION_MISO_GPIO    GPIOA
60
#define MOTION_MISO_PIN     GPIO_Pin_6
61
#define MOTION_MOSI_GPIO    GPIOA
62
#define MOTION_MOSI_PIN     GPIO_Pin_7
63
#define PROG_RX_GPIO        GPIOA
64
#define PROG_RX_PIN         GPIO_Pin_9
65
#define PROG_TX_GPIO        GPIOA
66
#define PROG_TX_PIN         GPIO_Pin_10
67
#define CAN_RX_GPIO         GPIOA
68
#define CAN_RX_PIN          GPIO_Pin_11
69
#define CAN_TX_GPIO         GPIOA
70
#define CAN_TX_PIN          GPIO_Pin_12
71
#define SWDIO_GPIO          GPIOA
72
#define SWDIO_PIN           GPIO_Pin_13
73
#define SWCLK_GPIO          GPIOA
74
#define SWCLK_PIN           GPIO_Pin_14
75
#define DRIVE_PWM2B_GPIO    GPIOA
76
#define DRIVE_PWM2B_PIN     GPIO_Pin_15
77

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

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

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

    
139
#define RESET_TIMEOUT_MS    100
140

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

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

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

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

    
160
volatile blBackupRegister_t backup_reg;
161

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

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

    
190

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

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

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

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

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

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

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

    
239
  setLed(BLT_FALSE);
240

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

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

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

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

    
277

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

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