LP-500 HoTT Telemetry added device definitions
[librepilot.git] / flight / targets / boards / discoveryf4bare / bootloader / main.c
blob09a54a0947a0a68ab0f6813b906feca532f1983e
1 /**
2 ******************************************************************************
3 * @addtogroup RevolutionBL Revolution BootLoader
4 * @brief These files contain the code to the Revolution Bootloader.
6 * @{
7 * @file main.c
8 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
9 * @brief This is the file with the main function of the Revolution BootLoader
10 * @see The GNU Public License (GPL) Version 3
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <pios.h>
30 #include <pios_board_info.h>
31 #include <op_dfu.h>
32 #include <pios_iap.h>
33 #include <fifo_buffer.h>
34 #include <pios_com_msg.h>
35 #include <pios_usbhook.h> /* PIOS_USBHOOK_* */
36 #include <stdbool.h>
37 #include <pios_board_init.h>
39 extern void FLASH_Download();
40 void check_bor();
41 #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1)
43 /* Private typedef -----------------------------------------------------------*/
44 typedef void (*pFunction)(void);
45 /* Private define ------------------------------------------------------------*/
46 /* Private macro -------------------------------------------------------------*/
47 /* Private variables ---------------------------------------------------------*/
48 pFunction Jump_To_Application;
49 uint32_t JumpAddress;
51 /// LEDs PWM
52 uint32_t period1 = 5000; // 5 mS
53 uint32_t sweep_steps1 = 100; // * 5 mS -> 500 mS
54 uint32_t period2 = 5000; // 5 mS
55 uint32_t sweep_steps2 = 100; // * 5 mS -> 500 mS
58 ////////////////////////////////////////
59 uint8_t tempcount = 0;
61 /* Extern variables ----------------------------------------------------------*/
62 DFUStates DeviceState;
63 int16_t status = 0;
64 bool JumpToApp = false;
65 bool GO_dfu = false;
66 bool USB_connected = false;
67 bool User_DFU_request = false;
68 static uint8_t mReceive_Buffer[63];
69 /* Private function prototypes -----------------------------------------------*/
70 uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count);
71 uint8_t processRX();
72 void jump_to_app();
74 int main()
76 PIOS_SYS_Init();
77 PIOS_Board_Init();
78 PIOS_IAP_Init();
80 // Make sure the brown out reset value for this chip
81 // is 2.7 volts
82 check_bor();
84 USB_connected = PIOS_USB_CheckAvailable(0);
86 if (PIOS_IAP_CheckRequest() == true) {
87 PIOS_DELAY_WaitmS(1000);
88 User_DFU_request = true;
89 PIOS_IAP_ClearRequest();
92 GO_dfu = (USB_connected == true) || (User_DFU_request == true);
94 if (GO_dfu == true) {
95 if (User_DFU_request == true) {
96 DeviceState = DFUidle;
97 } else {
98 DeviceState = BLidle;
100 } else {
101 JumpToApp = true;
104 uint32_t stopwatch = 0;
105 uint32_t prev_ticks = PIOS_DELAY_GetuS();
106 while (true) {
107 /* Update the stopwatch */
108 uint32_t elapsed_ticks = PIOS_DELAY_GetuSSince(prev_ticks);
109 prev_ticks += elapsed_ticks;
110 stopwatch += elapsed_ticks;
112 if (JumpToApp == true) {
113 jump_to_app();
116 switch (DeviceState) {
117 case Last_operation_Success:
118 case uploadingStarting:
119 case DFUidle:
120 period1 = 5000;
121 sweep_steps1 = 100;
122 PIOS_LED_Off(PIOS_LED_HEARTBEAT);
123 period2 = 0;
124 break;
125 case uploading:
126 period1 = 5000;
127 sweep_steps1 = 100;
128 period2 = 2500;
129 sweep_steps2 = 50;
130 break;
131 case downloading:
132 period1 = 2500;
133 sweep_steps1 = 50;
134 PIOS_LED_Off(PIOS_LED_HEARTBEAT);
135 period2 = 0;
136 break;
137 case BLidle:
138 period1 = 0;
139 PIOS_LED_On(PIOS_LED_HEARTBEAT);
140 period2 = 0;
141 break;
142 default: // error
143 period1 = 5000;
144 sweep_steps1 = 100;
145 period2 = 5000;
146 sweep_steps2 = 100;
149 if (period1 != 0) {
150 if (LedPWM(period1, sweep_steps1, stopwatch)) {
151 PIOS_LED_On(PIOS_LED_HEARTBEAT);
152 } else {
153 PIOS_LED_Off(PIOS_LED_HEARTBEAT);
155 } else {
156 PIOS_LED_On(PIOS_LED_HEARTBEAT);
159 if (period2 != 0) {
160 if (LedPWM(period2, sweep_steps2, stopwatch)) {
161 PIOS_LED_On(PIOS_LED_HEARTBEAT);
162 } else {
163 PIOS_LED_Off(PIOS_LED_HEARTBEAT);
165 } else {
166 PIOS_LED_Off(PIOS_LED_HEARTBEAT);
169 if (stopwatch > 50 * 1000 * 1000) {
170 stopwatch = 0;
172 if ((stopwatch > 6 * 1000 * 1000) && ((DeviceState == BLidle) || (DeviceState == DFUidle && !USB_connected))) {
173 JumpToApp = true;
176 processRX();
177 DataDownload(start);
181 void jump_to_app()
183 const struct pios_board_info *bdinfo = &pios_board_info_blob;
185 PIOS_LED_On(PIOS_LED_HEARTBEAT);
186 // Look at cm3_vectors struct in startup. In a fw image the first uint32_t contains the address of the top of irqstack
187 uint32_t fwIrqStackBase = (*(__IO uint32_t *)bdinfo->fw_base) & 0xFFFE0000;
188 // Check for the two possible irqstack locations (sram or core coupled sram)
189 if (fwIrqStackBase == 0x20000000 || fwIrqStackBase == 0x10000000) {
190 /* Jump to user application */
191 FLASH_Lock();
192 RCC_APB2PeriphResetCmd(0xffffffff, ENABLE);
193 RCC_APB1PeriphResetCmd(0xffffffff, ENABLE);
194 RCC_APB2PeriphResetCmd(0xffffffff, DISABLE);
195 RCC_APB1PeriphResetCmd(0xffffffff, DISABLE);
197 PIOS_USBHOOK_Deactivate();
199 JumpAddress = *(__IO uint32_t *)(bdinfo->fw_base + 4);
200 Jump_To_Application = (pFunction)JumpAddress;
201 /* Initialize user application's Stack Pointer */
202 __set_MSP(*(__IO uint32_t *)bdinfo->fw_base);
203 Jump_To_Application();
204 } else {
205 DeviceState = failed_jump;
206 return;
209 uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count)
211 uint32_t curr_step = (count / pwm_period) % pwm_sweep_steps; /* 0 - pwm_sweep_steps */
212 uint32_t pwm_duty = pwm_period * curr_step / pwm_sweep_steps; /* fraction of pwm_period */
214 uint32_t curr_sweep = (count / (pwm_period * pwm_sweep_steps)); /* ticks once per full sweep */
216 if (curr_sweep & 1) {
217 pwm_duty = pwm_period - pwm_duty; /* reverse direction in odd sweeps */
219 return ((count % pwm_period) > pwm_duty) ? 1 : 0;
222 uint8_t processRX()
224 if (PIOS_COM_MSG_Receive(PIOS_COM_TELEM_USB, mReceive_Buffer, sizeof(mReceive_Buffer))) {
225 processComand(mReceive_Buffer);
227 return true;
231 * Check the brown out reset threshold is 2.7 volts and if not
232 * resets it. This solves an issue that can prevent boards
233 * powering up with some BEC
235 void check_bor()
237 uint8_t bor = FLASH_OB_GetBOR();
239 if (bor != OB_BOR_LEVEL3) {
240 FLASH_OB_Unlock();
241 FLASH_OB_BORConfig(OB_BOR_LEVEL3);
242 FLASH_OB_Launch();
243 while (FLASH_WaitForLastOperation() == FLASH_BUSY) {
246 FLASH_OB_Lock();
247 while (FLASH_WaitForLastOperation() == FLASH_BUSY) {
253 int32_t platform_senddata(const uint8_t *msg, uint16_t msg_len)
255 return PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, msg, msg_len);