main.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. /*
  13. * Before compiling this example for NRF52, complete the following steps:
  14. * - Download the S212 SoftDevice from <a href="https://www.thisisant.com/developer/components/nrf52832" target="_blank">thisisant.com</a>.
  15. * - Extract the downloaded zip file and copy the S212 SoftDevice headers to <tt>\<InstallFolder\>/components/softdevice/s212/headers</tt>.
  16. * If you are using Keil packs, copy the files into a @c headers folder in your example folder.
  17. * - Make sure that @ref ANT_LICENSE_KEY in @c nrf_sdm.h is uncommented.
  18. */
  19. #include "dfu.h"
  20. #include "dfu_transport.h"
  21. #include "bootloader.h"
  22. #include "bootloader_util.h"
  23. #include <stdint.h>
  24. #include <string.h>
  25. #include <stddef.h>
  26. #include "nordic_common.h"
  27. #include "nrf.h"
  28. #include "app_error.h"
  29. #include "nrf_gpio.h"
  30. #include "nrf_soc.h"
  31. #include "nrf_delay.h"
  32. #include "ant_interface.h"
  33. #include "ant_parameters.h"
  34. #include "ant_error.h"
  35. #include "nrf.h"
  36. #include "app_scheduler.h"
  37. #include "app_timer_appsh.h"
  38. #include "nrf_error.h"
  39. #include "boards.h"
  40. #include "softdevice_handler.h"
  41. #include "pstorage_platform.h"
  42. #include "ant_boot_settings_api.h"
  43. #include "antfs_ota.h"
  44. #if !defined (S210_V3_STACK)
  45. #include "nrf_mbr.h"
  46. #endif // !S210_V3_STACK
  47. #include "ant_stack_config.h"
  48. #include "debug_pin.h"
  49. #include "app_timer_appsh.h"
  50. #include "softdevice_handler_appsh.h"
  51. #define ENABLE_BUTTON // include button detection
  52. //#define ENABLE_IO_LED // include LED status on N5DK1 i/o board
  53. #if defined (ENABLE_BUTTON)
  54. #if defined (BOARD_N5DK1)
  55. #define BOOTLOADER_BUTTON_PIN BUTTON_D /**< Button used to enter SW update mode. */
  56. #else
  57. #define BOOTLOADER_BUTTON_PIN BUTTON_1 /**< Button used to enter SW update mode. */
  58. #endif
  59. #endif
  60. #if defined (ENABLE_IO_LED)
  61. #define BOOTLOADER_ERROR_LED LED_C /**< N5DK Leds, set=led off, clr=led on */
  62. #define BOOTLOADER_ACTIVE_LED LED_D
  63. #endif // ENABLE_IO_LED
  64. #define APP_TIMER_PRESCALER 0 /**< Maximum number of simultaneously created timers. */
  65. #define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */
  66. #define SCHED_MAX_EVENT_DATA_SIZE MAX(ANT_STACK_EVT_MSG_BUF_SIZE, 0) /**< Maximum size of scheduler events. */
  67. #define SCHED_QUEUE_SIZE 20 /**< Maximum number of events in the scheduler queue. */
  68. /**@brief Function for error handling, which is called when an error has occurred.
  69. *
  70. * @warning This handler is an example only and does not fit a final product. You need to analyze
  71. * how your product is supposed to react in case of error.
  72. *
  73. * @param[in] error_code Error code supplied to the handler.
  74. * @param[in] line_num Line number where the handler is called.
  75. * @param[in] p_file_name Pointer to the file name.
  76. */
  77. #if defined (DEBUG_DFU_BOOTLOADER)
  78. uint32_t error_code_;
  79. uint32_t line_num_;
  80. const uint8_t * p_file_name_;
  81. #endif // DEBUG_DFU_BOOTLOADER
  82. void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
  83. {
  84. #if defined (DEBUG_DFU_BOOTLOADER)
  85. app_error_save_and_stop(id, pc, info);
  86. #endif // DEBUG_DFU_BOOTLOADER
  87. #if defined (ENABLE_IO_LED)
  88. // nrf_gpio_pin_set(BOOTLOADER_ERROR_LED);
  89. #endif // ENABLE_IO_LED
  90. // This call can be used for debug purposes during application development.
  91. // On assert, the system can only recover on reset.
  92. NVIC_SystemReset();
  93. }
  94. void HardFault_Handler(uint32_t ulProgramCounter, uint32_t ulLinkRegister)
  95. {
  96. (void)ulProgramCounter;
  97. (void)ulLinkRegister;
  98. NVIC_SystemReset();
  99. }
  100. /**@brief Callback function for asserts in the SoftDevice.
  101. *
  102. * @details This function will be called in case of an assert in the SoftDevice.
  103. *
  104. * @warning This handler is an example only and does not fit a final product. You need to analyze
  105. * how your product is supposed to react in case of Assert.
  106. * @warning On assert from the SoftDevice, the system can only recover on reset.
  107. *
  108. * @param[in] line_num Line number of the failing ASSERT call.
  109. * @param[in] file_name File name of the failing ASSERT call.
  110. */
  111. void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
  112. {
  113. app_error_handler(0xDEADBEEF, line_num, p_file_name);
  114. }
  115. #if defined (ENABLE_IO_LED)
  116. /**@brief Function for initialization of LEDs.
  117. *
  118. * @details Initializes all LEDs used by the application.
  119. */
  120. static void leds_init(void)
  121. {
  122. nrf_gpio_cfg_output(LED_A);
  123. nrf_gpio_cfg_output(LED_B);
  124. nrf_gpio_cfg_output(LED_C);
  125. nrf_gpio_cfg_output(LED_D);
  126. // turn on all leds
  127. nrf_gpio_pin_clear(LED_A);
  128. nrf_gpio_pin_clear(LED_B);
  129. nrf_gpio_pin_clear(LED_C);
  130. nrf_gpio_pin_clear(LED_D);
  131. }
  132. #endif // ENABLE_IO_LED
  133. #if defined (ENABLE_IO_LED)
  134. /**@brief Function for clearing the LEDs.
  135. *
  136. * @details Clears all LEDs used by the application.
  137. */
  138. static void leds_off(void)
  139. {
  140. nrf_gpio_pin_set(LED_A); // unused
  141. nrf_gpio_pin_set(LED_B); // unused
  142. nrf_gpio_pin_set(LED_C);
  143. nrf_gpio_pin_set(LED_D);
  144. }
  145. #endif // ENABLE_IO_LED
  146. /**@brief Function for the Timer initialization.
  147. *
  148. * @details Initializes the timer module.
  149. */
  150. static void timers_init(void)
  151. {
  152. // Initialize timer module, making it use the scheduler.
  153. APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, true);
  154. }
  155. #if defined (ENABLE_BUTTON)
  156. /**@brief Function for initializing the button module.
  157. */
  158. static void buttons_init(void)
  159. {
  160. nrf_gpio_cfg_sense_input(BOOTLOADER_BUTTON_PIN,
  161. BUTTON_PULL,
  162. NRF_GPIO_PIN_SENSE_LOW);
  163. }
  164. #endif // ENABLE_BUTTON
  165. /**@brief Function for dispatching a stack event to all modules with a stack event handler.
  166. *
  167. * @details This function is called from the scheduler in the main loop after a stack
  168. * event has been received.
  169. *
  170. * @param[in] event stack event.
  171. */
  172. static void sys_evt_dispatch(uint32_t event)
  173. {
  174. pstorage_sys_event_handler(event);
  175. }
  176. /**@brief Function for initializing the ANT stack.
  177. *
  178. * @details Initializes the SoftDevice and the BLE event interrupt.
  179. */
  180. static void ant_stack_init(void)
  181. {
  182. uint32_t err_code;
  183. nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
  184. err_code = softdevice_handler_init(&clock_lf_cfg, NULL, 0, softdevice_evt_schedule);
  185. APP_ERROR_CHECK(err_code);
  186. err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
  187. APP_ERROR_CHECK(err_code);
  188. // Configure ant stack regards used channels.
  189. err_code = ant_stack_static_config();
  190. APP_ERROR_CHECK(err_code);
  191. }
  192. /**@brief Function for event scheduler initialization.
  193. */
  194. static void scheduler_init(void)
  195. {
  196. APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
  197. }
  198. static uint32_t enter_boot_get (void )
  199. {
  200. uint32_t val = PARAM_FLAGS_ENTER_BOOT_BypassInit;
  201. if (((*ANT_BOOT_PARAM_FLAGS & PARAM_FLAGS_PARAM_VALID_Msk) >> PARAM_FLAGS_PARAM_VALID_Pos) == PARAM_FLAGS_PARAM_VALID_True )
  202. {
  203. val = (*ANT_BOOT_PARAM_FLAGS & PARAM_FLAGS_ENTER_BOOT_Msk) >> PARAM_FLAGS_ENTER_BOOT_Pos;
  204. }
  205. return val;
  206. }
  207. static void enter_boot_set (uint32_t value)
  208. {
  209. uint32_t ant_boot_param_flags = *ANT_BOOT_PARAM_FLAGS;
  210. uint32_t enter_boot = (ant_boot_param_flags >> PARAM_FLAGS_ENTER_BOOT_Pos) & PARAM_FLAGS_ENTER_BOOT_Msk;
  211. if (enter_boot == value)
  212. {
  213. return; // no need to rewrite the same value.
  214. }
  215. ant_boot_param_flags &= ~PARAM_FLAGS_ENTER_BOOT_Msk;
  216. ant_boot_param_flags |= value << PARAM_FLAGS_ENTER_BOOT_Pos;
  217. uint32_t err_code = blocking_flash_word_write(ANT_BOOT_PARAM_FLAGS, ant_boot_param_flags);
  218. APP_ERROR_CHECK(err_code);
  219. }
  220. static void enter_boot_update (void)
  221. {
  222. const bootloader_settings_t * p_bootloader_settings;
  223. bootloader_util_settings_get(&p_bootloader_settings);
  224. if(p_bootloader_settings->ap_image.st.bank == NEW_IMAGE_BANK_0 || p_bootloader_settings->ap_image.st.bank == NEW_IMAGE_BANK_1)
  225. {
  226. enter_boot_set(PARAM_FLAGS_ENTER_BOOT_BypassDone);
  227. }
  228. else
  229. {
  230. if (p_bootloader_settings->valid_app != BOOTLOADER_SETTINGS_INVALID_APPLICATION)
  231. {
  232. enter_boot_set(PARAM_FLAGS_ENTER_BOOT_BypassDone);
  233. return;
  234. }
  235. enter_boot_set(PARAM_FLAGS_ENTER_BOOT_EnterBoot);
  236. }
  237. // If the current application has been invalidated, then application's self protection is of no use now.
  238. // Lets clear it.
  239. if (p_bootloader_settings->valid_app == BOOTLOADER_SETTINGS_INVALID_APPLICATION)
  240. {
  241. if(*ANT_BOOT_APP_SIZE != APP_SIZE_Empty)
  242. {
  243. uint32_t err_code = blocking_flash_word_write(ANT_BOOT_APP_SIZE, APP_SIZE_Clear);
  244. APP_ERROR_CHECK(err_code);
  245. }
  246. }
  247. }
  248. /**@brief Function for application main entry.
  249. */
  250. int main(void)
  251. {
  252. uint32_t err_code;
  253. bool bootloader_is_pushed = false;
  254. #if defined (ENABLE_IO_LED)
  255. leds_init();
  256. #endif // ENABLE_IO_LED
  257. #if defined (ENABLE_BUTTON)
  258. buttons_init();
  259. #endif
  260. #if defined (DEBUG_DFU_BOOTLOADER)
  261. NRF_GPIO->DIRSET = 0x40000908; //stack debugging
  262. DBG_PIN_DIR_INIT;
  263. #endif //DEBUG_DFU_BOOTLOADER
  264. #if defined (DBG_DFU_BOOTLOADER_PATH)
  265. DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);
  266. #endif //DBG_DFU_BOOTLOADER_PATH
  267. // This check ensures that the defined fields in the bootloader corresponds with actual
  268. // setting in the chip.
  269. APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
  270. APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE);
  271. #if !defined (S210_V3_STACK)
  272. sd_mbr_command_t com = {SD_MBR_COMMAND_INIT_SD, };
  273. err_code = sd_mbr_command(&com);
  274. APP_ERROR_CHECK(err_code);
  275. err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_REGION_START);
  276. APP_ERROR_CHECK(err_code);
  277. err_code = bootloader_dfu_sd_update_continue();
  278. APP_ERROR_CHECK(err_code);
  279. err_code = bootloader_dfu_bl_update_continue();
  280. APP_ERROR_CHECK(err_code);
  281. #endif // !S210_V3_STACK
  282. // Initialize.
  283. timers_init();
  284. (void)bootloader_init();
  285. ant_stack_init();
  286. scheduler_init();
  287. #if defined (ENABLE_BUTTON)
  288. // Push button switch
  289. bootloader_is_pushed = ((nrf_gpio_pin_read(BOOTLOADER_BUTTON_PIN) == 0) ? true: false);
  290. if (bootloader_is_pushed)
  291. {
  292. enter_boot_set(PARAM_FLAGS_ENTER_BOOT_EnterBoot);
  293. }
  294. #endif // ENABLE_BUTTON
  295. if ((enter_boot_get() == PARAM_FLAGS_ENTER_BOOT_EnterBoot) ||
  296. (bootloader_is_pushed) ||
  297. (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))
  298. {
  299. #if defined (DBG_DFU_BOOTLOADER_PATH)
  300. DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);
  301. #endif //DBG_DFU_BOOTLOADER_PATH
  302. #if defined (ENABLE_IO_LED)
  303. leds_off();
  304. nrf_gpio_pin_clear(BOOTLOADER_ACTIVE_LED);
  305. #endif // ENABLE_IO_LED
  306. // Initiate an update of the firmware.
  307. err_code = bootloader_dfu_start();
  308. APP_ERROR_CHECK(err_code);
  309. enter_boot_update();
  310. }
  311. #if defined (ENABLE_IO_LED)
  312. leds_off();
  313. #endif // ENABLE_IO_LED
  314. err_code = bootloader_dfu_ap_update_continue();
  315. APP_ERROR_CHECK(err_code);
  316. if (bootloader_app_is_valid(DFU_BANK_0_REGION_START))
  317. {
  318. #if defined (DBG_DFU_BOOTLOADER_PATH)
  319. DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);
  320. #endif //DBG_DFU_BOOTLOADER_PATH
  321. // Select a bank region to use as application region.
  322. // @note: Only applications running from DFU_BANK_0_REGION_START is supported.
  323. bootloader_app_start(DFU_BANK_0_REGION_START);
  324. }
  325. #if defined (DBG_DFU_BOOTLOADER_PATH)
  326. DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);DEBUG_PIN_FALL(DBG_DFU_BOOTLOADER_PATH);
  327. #endif //DBG_DFU_BOOTLOADER_PATH
  328. NVIC_SystemReset();
  329. }