use PWM0 & PWM1 for led blinky fix #14
This commit is contained in:
		| @@ -117,7 +117,7 @@ static void forced_startup_dfu_timer_handler(void * p_context) | |||||||
|  */ |  */ | ||||||
| static void wait_for_events(void) | static void wait_for_events(void) | ||||||
| { | { | ||||||
|     for (;;) |   for ( ;; ) | ||||||
|   { |   { | ||||||
|     // Wait in low power state for any events. |     // Wait in low power state for any events. | ||||||
| //    uint32_t err_code = sd_app_evt_wait(); | //    uint32_t err_code = sd_app_evt_wait(); | ||||||
| @@ -127,20 +127,24 @@ static void wait_for_events(void) | |||||||
|     app_sched_execute(); |     app_sched_execute(); | ||||||
|  |  | ||||||
| #ifdef NRF52840_XXAA | #ifdef NRF52840_XXAA | ||||||
|  |     // usb is not enabled in OTA | ||||||
|  |     if ( !is_ota() ) | ||||||
|  |     { | ||||||
|       tusb_task(); |       tusb_task(); | ||||||
|       tud_cdc_write_flush(); |       tud_cdc_write_flush(); | ||||||
|  |     } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     if ((m_update_status == BOOTLOADER_COMPLETE) || |     if ((m_update_status == BOOTLOADER_COMPLETE) || | ||||||
|         (m_update_status == BOOTLOADER_TIMEOUT) || |         (m_update_status == BOOTLOADER_TIMEOUT) || | ||||||
|             (m_update_status == BOOTLOADER_RESET)) |         (m_update_status == BOOTLOADER_RESET) ) | ||||||
|     { |     { | ||||||
|       // When update has completed or a timeout/reset occured we will return. |       // When update has completed or a timeout/reset occured we will return. | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Forced startup dfu mode timeout without any received packet |     // Forced startup dfu mode timeout without any received packet | ||||||
|         if (_terminate_startup_dfu) return; |     if ( _terminate_startup_dfu ) return; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										146
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -34,6 +34,7 @@ | |||||||
|  |  | ||||||
| #include "nrfx.h" | #include "nrfx.h" | ||||||
| #include "nrfx_power.h" | #include "nrfx_power.h" | ||||||
|  | #include "nrfx_pwm.h" | ||||||
|  |  | ||||||
| #include "nordic_common.h" | #include "nordic_common.h" | ||||||
| #include "sdk_common.h" | #include "sdk_common.h" | ||||||
| @@ -124,9 +125,14 @@ STATIC_ASSERT( APPDATA_ADDR_START == 0x6D000); | |||||||
|  |  | ||||||
| void adafruit_factory_reset(void); | void adafruit_factory_reset(void); | ||||||
|  |  | ||||||
|  | /* | ||||||
| // Adafruit for Blink pattern |  * Blinking patterns: | ||||||
| bool _fast_blink = false; |  * - DFU Serial     : LED Status blink | ||||||
|  |  * - DFU OTA        : LED Status & Conn blink at the same time | ||||||
|  |  * - DFU Flashing   : LED Status blink 2x fast | ||||||
|  |  * - Factory Reset  : LED Status blink 2x fast | ||||||
|  |  * - Fatal Error    : LED Status & Conn blink one after another | ||||||
|  |  */ | ||||||
| bool _ota_connected = false; | bool _ota_connected = false; | ||||||
|  |  | ||||||
| // true if ble, false if serial | // true if ble, false if serial | ||||||
| @@ -134,55 +140,68 @@ bool _ota_update = false; | |||||||
|  |  | ||||||
| bool is_ota(void) { return _ota_update; } | bool is_ota(void) { return _ota_update; } | ||||||
|  |  | ||||||
|  | #define PWM_MAXCOUNT      25000 | ||||||
|  | uint16_t _pwm_red_seq0 [NRF_PWM_CHANNEL_COUNT] = { PWM_MAXCOUNT/2, 0, 0 , 0 }; | ||||||
| /* | uint16_t _pwm_blue_seq0[NRF_PWM_CHANNEL_COUNT] = { PWM_MAXCOUNT/2, 0, 0 , 0 }; | ||||||
|  * Blinking function, there are a few patterns |  | ||||||
|  * - DFU Serial     : LED Status blink |  | ||||||
|  * - DFU OTA        : LED Status & Conn blink at the same time |  | ||||||
|  * - DFU Flashing   : LED Status blink 2x fast |  | ||||||
|  * - Factory Reset  : LED Status blink 2x fast |  | ||||||
|  * - Fatal Error    : LED Status & Conn blink one after another |  | ||||||
|  */ |  | ||||||
| static void blinky_handler(void) |  | ||||||
| { |  | ||||||
|   static uint8_t state = 0; |  | ||||||
|   static uint32_t count = 0; |  | ||||||
|  |  | ||||||
|   count++; |  | ||||||
|  |  | ||||||
|   // if not uploading then blink slow (interval/2) |  | ||||||
|   if ( !_fast_blink && count%2 ) return; |  | ||||||
|  |  | ||||||
|   state = 1-state; |  | ||||||
|  |  | ||||||
|   led_control(LED_RED, state); |  | ||||||
|  |  | ||||||
|   // Blink LED BLUE if OTA mode and not connected |  | ||||||
|   if (is_ota() && !_ota_connected) |  | ||||||
|   { |  | ||||||
|     led_control(LED_BLUE, state); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Feed all Watchdog just in case application enable it (WDT last through a jump from application to bootloader) |  | ||||||
|   if ( nrf_wdt_started() ) |  | ||||||
|   { |  | ||||||
|     for (uint8_t i=0; i<8; i++) nrf_wdt_reload_request_set(i); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void SysTick_Handler(void) |  | ||||||
| { |  | ||||||
|   blinky_handler(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void led_blink_fast(bool enable) | void led_blink_fast(bool enable) | ||||||
| { | { | ||||||
|   _fast_blink = enable; |   if ( enable ) | ||||||
|  |   { | ||||||
|  |     NRF_PWM0->MODE = PWM_MODE_UPDOWN_Up; | ||||||
|  |   }else | ||||||
|  |   { | ||||||
|  |     NRF_PWM0->MODE = PWM_MODE_UPDOWN_UpAndDown; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* use PWM for blinky to prevent inconsistency due to MCU blocking in flash operation | ||||||
|  |  * clock = 125khz --> resolution = 8us | ||||||
|  |  * top value = 25000 -> period = 200 ms (fast blink) --> up and down mode = 400 ms ( slow blink ) | ||||||
|  |  */ | ||||||
|  | void led_pwm_init(NRF_PWM_Type* pwm, uint32_t led_pin) | ||||||
|  | { | ||||||
|  |   pwm->MODE            = PWM_MODE_UPDOWN_UpAndDown; | ||||||
|  |   pwm->COUNTERTOP      = PWM_MAXCOUNT; | ||||||
|  |   pwm->PRESCALER       = PWM_PRESCALER_PRESCALER_DIV_128; | ||||||
|  |   pwm->DECODER         = PWM_DECODER_LOAD_Individual; | ||||||
|  |   pwm->LOOP            = 0; | ||||||
|  |  | ||||||
|  |   pwm->SEQ[0].PTR      = (uint32_t) (led_pin == LED_RED ? _pwm_red_seq0 : _pwm_blue_seq0); | ||||||
|  |   pwm->SEQ[0].CNT      = NRF_PWM_CHANNEL_COUNT; // default mode is Individual --> count must be 4 | ||||||
|  |   pwm->SEQ[0].REFRESH  = 0; | ||||||
|  |   pwm->SEQ[0].ENDDELAY = 0; | ||||||
|  |  | ||||||
|  |   pwm->PSEL.OUT[0] = led_pin; | ||||||
|  |  | ||||||
|  |   pwm->ENABLE = 1; | ||||||
|  |   pwm->TASKS_SEQSTART[0] = 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void led_pwm_teardown(NRF_PWM_Type* pwm) | ||||||
|  | { | ||||||
|  |   pwm->TASKS_SEQSTART[0] = 0; | ||||||
|  |   pwm->ENABLE            = 0; | ||||||
|  |  | ||||||
|  |   pwm->PSEL.OUT[0] = 0xFFFFFFFF; | ||||||
|  |  | ||||||
|  |   pwm->MODE        = 0; | ||||||
|  |   pwm->COUNTERTOP  = 0x3FF; | ||||||
|  |   pwm->PRESCALER   = 0; | ||||||
|  |   pwm->DECODER     = 0; | ||||||
|  |   pwm->LOOP        = 0; | ||||||
|  |   pwm->SEQ[0].PTR  = 0; | ||||||
|  |   pwm->SEQ[0].CNT  = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| void board_init(void) | void board_init(void) | ||||||
| { | { | ||||||
|  |   // stop WDT if started by application, when jumping from application using BLE DFU | ||||||
|  |   if ( NRF_WDT->RUNSTATUS ) | ||||||
|  |   { | ||||||
|  |     NRF_WDT->TASKS_START = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   button_init(BUTTON_DFU); |   button_init(BUTTON_DFU); | ||||||
|   button_init(BUTTON_FRESET); |   button_init(BUTTON_FRESET); | ||||||
|   NRFX_DELAY_US(100); // wait for the pin state is stable |   NRFX_DELAY_US(100); // wait for the pin state is stable | ||||||
| @@ -193,21 +212,19 @@ void board_init(void) | |||||||
|   led_off(LED_RED); |   led_off(LED_RED); | ||||||
|   led_off(LED_BLUE); |   led_off(LED_BLUE); | ||||||
|  |  | ||||||
|  |   // use PMW0 for LED RED | ||||||
|  |   led_pwm_init(NRF_PWM0, LED_RED); | ||||||
|  |  | ||||||
|   // Init scheduler |   // Init scheduler | ||||||
|   APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); |   APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); | ||||||
|  |  | ||||||
|   // Init app timer (use RTC1) |  | ||||||
|   app_timer_init(); |  | ||||||
|  |  | ||||||
|   // Configure Systick for led blinky |  | ||||||
|   extern uint32_t SystemCoreClock; |  | ||||||
|   SysTick_Config(SystemCoreClock/(1000/LED_BLINK_INTERVAL)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void board_teardown(void) | void board_teardown(void) | ||||||
| { | { | ||||||
|   // Disable systick, turn off LEDs |   // Disable and reset PWM for LED | ||||||
|   SysTick->CTRL = 0; |   led_pwm_teardown(NRF_PWM0); | ||||||
|  |  | ||||||
|  |   if ( is_ota() ) led_pwm_teardown(NRF_PWM1); | ||||||
|  |  | ||||||
|   led_off(LED_BLUE); |   led_off(LED_BLUE); | ||||||
|   led_off(LED_RED); |   led_off(LED_RED); | ||||||
| @@ -235,7 +252,7 @@ void softdev_mbr_init(void) | |||||||
|  *                             be initialized if a chip reset has occured. Soft reset (jump ) from |  *                             be initialized if a chip reset has occured. Soft reset (jump ) from | ||||||
|  *                             application must not reinitialize the SoftDevice. |  *                             application must not reinitialize the SoftDevice. | ||||||
|  */ |  */ | ||||||
| uint32_t softdev_init(bool init_softdevice) | static uint32_t softdev_init(bool init_softdevice) | ||||||
| { | { | ||||||
|   if (init_softdevice) softdev_mbr_init(); |   if (init_softdevice) softdev_mbr_init(); | ||||||
|  |  | ||||||
| @@ -339,14 +356,25 @@ int main(void) | |||||||
|  |  | ||||||
|   if ( dfu_start || !bootloader_app_is_valid(DFU_BANK_0_REGION_START) ) |   if ( dfu_start || !bootloader_app_is_valid(DFU_BANK_0_REGION_START) ) | ||||||
|   { |   { | ||||||
|     // Enable BLE if in OTA |  | ||||||
|     if ( _ota_update ) |     if ( _ota_update ) | ||||||
|     { |     { | ||||||
|  |       // Enable BLE if in OTA | ||||||
|  |       led_pwm_init(NRF_PWM1, LED_BLUE); | ||||||
|  |  | ||||||
|       softdev_init(!sd_inited); |       softdev_init(!sd_inited); | ||||||
|       sd_inited = true; |       sd_inited = true; | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |       // Init app timer (use RTC1) | ||||||
|  |       app_timer_init(); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       // Init app timer (use RTC1) | ||||||
|  |       app_timer_init(); | ||||||
|  |  | ||||||
|  |       // otherwise USB for Serial & UF2 | ||||||
|       usb_init(); |       usb_init(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Initiate an update of the firmware. |     // Initiate an update of the firmware. | ||||||
|     APP_ERROR_CHECK( bootloader_dfu_start(_ota_update, 0) ); |     APP_ERROR_CHECK( bootloader_dfu_start(_ota_update, 0) ); | ||||||
| @@ -453,12 +481,12 @@ uint32_t proc_ble(void) | |||||||
|     { |     { | ||||||
|       case BLE_GAP_EVT_CONNECTED: |       case BLE_GAP_EVT_CONNECTED: | ||||||
|         _ota_connected = true; |         _ota_connected = true; | ||||||
|         led_on(LED_BLUE); |         _pwm_blue_seq0[0] = PWM_MAXCOUNT; | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|       case BLE_GAP_EVT_DISCONNECTED: |       case BLE_GAP_EVT_DISCONNECTED: | ||||||
|         _ota_connected = false; |         _ota_connected = false; | ||||||
|         led_off(LED_BLUE); |         _pwm_blue_seq0[0] = PWM_MAXCOUNT/2; | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|       default: break; |       default: break; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user