From 2ece2daf9077b6515bec028c077002887152513b Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 4 Dec 2018 13:45:55 -0800 Subject: [PATCH] Rework LED flashing and add Particle's boards --- Makefile | 24 +- .../libraries/bootloader_dfu/bootloader.c | 9 +- .../bootloader_dfu/dfu_transport_ble.c | 7 +- .../bootloader_dfu/dfu_transport_serial.c | 15 +- src/boards.c | 224 ++++++++++++------ src/boards.h | 58 +++-- src/boards/feather_nrf52832.h | 6 +- src/boards/feather_nrf52840_express.h | 9 +- src/boards/particle_argon.h | 77 ++++++ src/boards/particle_boron.h | 81 +++++++ src/boards/particle_xenon.h | 77 ++++++ src/boards/pca10056.h | 4 +- src/boards/pca10059.h | 10 +- src/main.c | 30 +-- src/usb/uf2/ghostfat.c | 7 +- src/usb/uf2/uf2cfg.h | 18 +- src/usb/usb.c | 11 +- 17 files changed, 501 insertions(+), 166 deletions(-) create mode 100644 src/boards/particle_argon.h create mode 100644 src/boards/particle_boron.h create mode 100644 src/boards/particle_xenon.h diff --git a/Makefile b/Makefile index ed6a386..dc07ba0 100644 --- a/Makefile +++ b/Makefile @@ -53,9 +53,7 @@ endif ifeq ($(OS),Windows_NT) PROGFILES = C:/Program Files (x86) -GNU_INSTALL_ROOT = $(PROGFILES)/GNU Tools ARM Embedded/7 2018-q2-update -else -GNU_INSTALL_ROOT = /usr +GNU_INSTALL_ROOT = $(PROGFILES)/GNU Tools ARM Embedded/7 2018-q2-update/bin/ endif MK := mkdir @@ -70,14 +68,14 @@ endif GNU_PREFIX = arm-none-eabi # Toolchain commands -CC := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc' -AS := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as' -AR := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar' -r -LD := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld' -NM := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm' -OBJDUMP := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump' -OBJCOPY := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy' -SIZE := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size' +CC := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-gcc' +AS := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-as' +AR := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ar' -r +LD := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ld' +NM := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-nm' +OBJDUMP := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objdump' +OBJCOPY := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objcopy' +SIZE := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-size' #function for removing duplicates in a list remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1)))) @@ -87,7 +85,7 @@ remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-ou #********************************* BOARD_LIST = $(sort $(subst .h,,$(subst src/boards/,,$(wildcard src/boards/*.h)))) -NRF52840_BOARDLIST = pca10056 pca10059 feather_nrf52840_express +NRF52840_BOARDLIST = pca10056 pca10059 feather_nrf52840_express particle_argon particle_boron particle_xenon IS_NRF52840 = $(filter $(BOARD),$(NRF52840_BOARDLIST)) ifeq ($(filter $(MAKECMDGOALS),all-board all-release help),) @@ -370,7 +368,7 @@ all-board: all-release: $(call _make_all_board,clean all release) - + help: @echo To flash (with jlink) a pre-built binary with a specific version to a board @echo $$ make BOARD=feather_nrf52840_express VERSION=6.1.1r0 flash diff --git a/lib/sdk11/components/libraries/bootloader_dfu/bootloader.c b/lib/sdk11/components/libraries/bootloader_dfu/bootloader.c index f80f83a..a61739c 100644 --- a/lib/sdk11/components/libraries/bootloader_dfu/bootloader.c +++ b/lib/sdk11/components/libraries/bootloader_dfu/bootloader.c @@ -136,6 +136,8 @@ static void wait_for_events(void) } #endif + led_tick(); + if ((m_update_status == BOOTLOADER_COMPLETE) || (m_update_status == BOOTLOADER_TIMEOUT) || (m_update_status == BOOTLOADER_RESET) ) @@ -221,8 +223,8 @@ void bootloader_dfu_update_process(dfu_update_status_t update_status) else if (update_status.status_code == DFU_UPDATE_SD_COMPLETE) { settings.bank_0_crc = update_status.app_crc; - settings.bank_0_size = update_status.sd_size + - update_status.bl_size + + settings.bank_0_size = update_status.sd_size + + update_status.bl_size + update_status.app_size; settings.bank_0 = BANK_VALID_SD; settings.bank_1 = BANK_INVALID_APP; @@ -326,7 +328,7 @@ uint32_t bootloader_dfu_start(bool ota, uint32_t timeout_ms) uint32_t err_code; // Clear swap if banked update is used. - err_code = dfu_init(); + err_code = dfu_init(); VERIFY_SUCCESS(err_code); if ( ota ) @@ -467,4 +469,3 @@ void bootloader_settings_get(bootloader_settings_t * const p_settings) p_settings->app_image_size = p_bootloader_settings->app_image_size; p_settings->sd_image_start = p_bootloader_settings->sd_image_start; } - diff --git a/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_ble.c b/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_ble.c index ac33c51..c88a24c 100644 --- a/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_ble.c +++ b/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_ble.c @@ -589,7 +589,7 @@ static void on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) break; case BLE_DFU_PACKET_WRITE: - led_red_blink_fast(true); + led_state(STATE_WRITING_STARTED); on_dfu_pkt_write(p_dfu, p_evt); break; @@ -741,6 +741,7 @@ static void on_ble_evt(ble_evt_t * p_ble_evt) case BLE_GAP_EVT_CONNECTED: m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; m_is_advertising = false; + led_state(STATE_BLE_CONNECTED); break; case BLE_GAP_EVT_DISCONNECTED: @@ -750,9 +751,9 @@ static void on_ble_evt(ble_evt_t * p_ble_evt) m_direct_adv_cnt = APP_DIRECTED_ADV_TIMEOUT; - led_red_blink_fast(false); + led_state(STATE_BLE_DISCONNECTED); - err_code = sd_ble_gatts_sys_attr_get(m_conn_handle, + err_code = sd_ble_gatts_sys_attr_get(m_conn_handle, sys_attr, &sys_attr_len, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS); diff --git a/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_serial.c b/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_serial.c index bef9da5..e3e8dc2 100644 --- a/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_serial.c +++ b/lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_serial.c @@ -106,7 +106,7 @@ static uint32_t data_queue_element_free(uint8_t element_index) uint32_t retval; retval = NRF_ERROR_INVALID_PARAM; - + if (MAX_BUFFERS > element_index) { p_data = (uint8_t *)DATA_QUEUE_ELEMENT_GET_PDATA(element_index); @@ -137,7 +137,7 @@ static uint32_t data_queue_element_alloc(uint8_t * p_element_index, uint8_t pack uint32_t index; retval = NRF_ERROR_NO_MEM; - + if (INVALID_PACKET == packet_type) { retval = NRF_ERROR_INVALID_PARAM; @@ -216,7 +216,7 @@ static void process_dfu_packet(void * p_event_data, uint16_t event_size) break; case START_PACKET: - packet->params.start_packet = + packet->params.start_packet = (dfu_start_packet_t*)packet->params.data_packet.p_data_packet; retval = dfu_start_pkt_handle(packet); APP_ERROR_CHECK(retval); @@ -227,14 +227,14 @@ static void process_dfu_packet(void * p_event_data, uint16_t event_size) retval = dfu_init_pkt_complete(); APP_ERROR_CHECK(retval); - led_red_blink_fast(true); + led_state(STATE_WRITING_STARTED); break; case STOP_DATA_PACKET: (void)dfu_image_validate(); (void)dfu_image_activate(); - led_red_blink_fast(false); + led_state(STATE_WRITING_FINISHED); // Break the loop by returning. return; @@ -273,7 +273,7 @@ void rpc_transport_event_handler(hci_transport_evt_t event) retval = app_sched_event_put(NULL, 0, process_dfu_packet); } } - + if (p_rpc_cmd_buffer != NULL && NRF_SUCCESS != retval) { // Free the packet that could not be processed. @@ -308,7 +308,6 @@ uint32_t dfu_transport_serial_close(void) { // Remove all buffered packets. data_queue_flush(); - + return hci_transport_close(); } - diff --git a/src/boards.c b/src/boards.c index e7e1dfe..13d34b1 100644 --- a/src/boards.c +++ b/src/boards.c @@ -45,20 +45,11 @@ #define SCHED_MAX_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Maximum size of scheduler events. */ #define SCHED_QUEUE_SIZE 30 /**< Maximum number of events in the scheduler queue. */ -/* use PWM for blinky to prevent inconsistency due to MCU blocking in flash operation - * clock = 125khz --> resolution = 8us - * top value = 25000 -> period = 200 ms - * Mode up -> toggle every 100 ms = fast blink - * Mode up and down = 400 ms = slow blink - */ -#define PWM_MAXCOUNT 25000 -#define PWM_CHANNEL_NUM 4 - - -uint16_t _pwm_red_seq [PWM_CHANNEL_NUM] = { PWM_MAXCOUNT/2, 0, 0 , 0 }; -uint16_t _pwm_blue_seq[PWM_CHANNEL_NUM] = { PWM_MAXCOUNT/2, 0, 0 , 0 }; - //------------- IMPLEMENTATION -------------// +#ifdef OUTPUT_500HZ_PIN +void init_clock_pwm(uint32_t pin); +void clock_pwm_teardown(void); +#endif void board_init(void) { @@ -73,22 +64,16 @@ void board_init(void) button_init(BUTTON_FRESET); NRFX_DELAY_US(100); // wait for the pin state is stable - // LED init - nrf_gpio_cfg_output(LED_RED); - nrf_gpio_cfg_output(LED_BLUE); - led_off(LED_RED); - led_off(LED_BLUE); - // use PMW0 for LED RED - led_pwm_init(LED_RED); + led_pwm_init(LED_PRIMARY, LED_PRIMARY_PIN); + #if LEDS_NUMBER > 1 + led_pwm_init(LED_SECONDARY, LED_SECONDARY_PIN); + #endif // use neopixel for use enumeration -#ifdef LED_NEOPIXEL +#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) extern void neopixel_init(void); neopixel_init(); - - uint8_t grb[3] = { 0, 32, 0 }; - neopixel_write(grb); #endif // Init scheduler @@ -100,17 +85,13 @@ void board_init(void) void board_teardown(void) { - // Disable and reset PWM for LED - led_pwm_teardown(LED_RED); + // Disable and reset PWM for LEDs + led_pwm_teardown(); -#ifdef LED_NEOPIXEL +#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) extern void neopixel_teardown(void); neopixel_teardown(); #endif - - led_off(LED_BLUE); - led_off(LED_RED); - // Button // Stop RTC1 used by app_timer @@ -146,58 +127,129 @@ void pwm_teardown(NRF_PWM_Type* pwm ) pwm->SEQ[0].CNT = 0; } -void led_pwm_init(uint32_t led_pin) -{ - NRF_PWM_Type* pwm = (led_pin == LED_RED) ? NRF_PWM0 : NRF_PWM1; +static uint16_t led_duty_cycles[PWM0_CH_NUM]; - pwm->MODE = PWM_MODE_UPDOWN_UpAndDown; - pwm->COUNTERTOP = PWM_MAXCOUNT; - pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_128; +#if LEDS_NUMBER > PWM0_CH_NUM +#error "Only " PWM0_CH_NUM " concurrent status LEDs are supported." +#endif + +void led_pwm_init(uint32_t led_index, uint32_t led_pin) +{ + NRF_PWM_Type* pwm = NRF_PWM0; + + nrf_gpio_cfg_output(led_pin); + pwm->PSEL.OUT[led_index] = led_pin; + + pwm->ENABLE = 1; + pwm->MODE = PWM_MODE_UPDOWN_Up; + pwm->COUNTERTOP = 0xff; + pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_16; pwm->DECODER = PWM_DECODER_LOAD_Individual; pwm->LOOP = 0; - pwm->SEQ[0].PTR = (uint32_t) (led_pin == LED_RED ? _pwm_red_seq : _pwm_blue_seq); - pwm->SEQ[0].CNT = PWM_CHANNEL_NUM; // default mode is Individual --> count must be 4 + pwm->SEQ[0].PTR = (uint32_t) (led_duty_cycles); + pwm->SEQ[0].CNT = 4; // 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->LOOP = 0; pwm->TASKS_SEQSTART[0] = 1; } -void led_pwm_teardown(uint32_t led_pin) +void led_pwm_teardown(void) { - pwm_teardown ((led_pin == LED_RED) ? NRF_PWM0 : NRF_PWM1); + pwm_teardown(NRF_PWM0); } -void led_pwm_disable(uint32_t led_pin) +void led_pwm_duty_cycle(uint32_t led_index, uint16_t duty_cycle) { - NRF_PWM_Type* pwm = (led_pin == LED_RED) ? NRF_PWM0 : NRF_PWM1; - - pwm->TASKS_SEQSTART[0] = 0; - pwm->ENABLE = 0; + led_duty_cycles[led_index] = duty_cycle; + nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_SEQEND0); + nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0); } -void led_pwm_enable(uint32_t led_pin) -{ - NRF_PWM_Type* pwm = (led_pin == LED_RED) ? NRF_PWM0 : NRF_PWM1; +static uint32_t primary_cycle_length; +#ifdef LED_SECONDARY_PIN +static uint32_t secondary_cycle_length; +#endif +void led_tick() { + uint32_t millis = tusb_hal_millis(); - pwm->ENABLE = 1; - pwm->TASKS_SEQSTART[0] = 1; + uint32_t cycle = millis % primary_cycle_length; + uint32_t half_cycle = primary_cycle_length / 2; + if (cycle > half_cycle) { + cycle = primary_cycle_length - cycle; + } + uint16_t duty_cycle = 0x4f * cycle / half_cycle; + #if LED_STATE_ON == 1 + duty_cycle = 0xff - duty_cycle; + #endif + led_pwm_duty_cycle(LED_PRIMARY, duty_cycle); + + #ifdef LED_SECONDARY_PIN + cycle = millis % secondary_cycle_length; + half_cycle = secondary_cycle_length / 2; + if (cycle > half_cycle) { + cycle = secondary_cycle_length - cycle; + } + duty_cycle = 0x8f * cycle / half_cycle; + #if LED_STATE_ON == 1 + duty_cycle = 0xff - duty_cycle; + #endif + led_pwm_duty_cycle(LED_SECONDARY, duty_cycle); + #endif } - -void led_red_blink_fast(bool enable) +static uint32_t rgb_color; +static bool temp_color_active = false; +void led_state(uint32_t state) { - if ( enable ) - { - NRF_PWM0->MODE = PWM_MODE_UPDOWN_Up; - }else - { - NRF_PWM0->MODE = PWM_MODE_UPDOWN_UpAndDown; - } + uint32_t new_rgb_color = rgb_color; + uint32_t temp_color = 0; + switch (state) { + case STATE_USB_MOUNTED: + new_rgb_color = 0x00ff00; + primary_cycle_length = 4000; + break; + case STATE_BOOTLOADER_STARTED: + case STATE_USB_UNMOUNTED: + new_rgb_color = 0xff0000; + primary_cycle_length = 300; + break; + case STATE_WRITING_STARTED: + temp_color = 0xff0000; + break; + case STATE_WRITING_FINISHED: + // Empty means to unset any temp colors. + break; + case STATE_BLE_CONNECTED: + new_rgb_color = 0x0000ff; + #ifdef LED_SECONDARY_PIN + secondary_cycle_length = 500; + #else + primary_cycle_length = 500; + #endif + break; + case STATE_BLE_DISCONNECTED: + new_rgb_color = 0xff00ff; + #ifdef LED_SECONDARY_PIN + secondary_cycle_length = 300; + #else + primary_cycle_length = 300; + #endif + break; + default: + break; + } + new_rgb_color &= BOARD_RGB_BRIGHTNESS; + if (temp_color != 0){ + neopixel_write((uint8_t*)&temp_color); + temp_color_active = true; + } else if (new_rgb_color != rgb_color) { + neopixel_write((uint8_t*)&new_rgb_color); + rgb_color = new_rgb_color; + } else if (temp_color_active) { + neopixel_write((uint8_t*)&rgb_color); + } } #if LED_NEOPIXEL @@ -267,10 +319,11 @@ void neopixel_teardown(void) // write 3 bytes color to a built-in neopixel void neopixel_write (uint8_t *pixels) { + uint8_t grb[NEO_NUMBYTE] = {pixels[1], pixels[2], pixels[0]}; uint16_t pos = 0; // bit position for ( uint16_t n = 0; n < NEO_NUMBYTE; n++ ) { - uint8_t pix = pixels[n]; + uint8_t pix = grb[n]; for ( uint8_t mask = 0x80; mask > 0; mask >>= 1 ) { @@ -280,8 +333,8 @@ void neopixel_write (uint8_t *pixels) } // Zero padding to indicate the end of sequence - pixels_pattern[++pos] = 0 | (0x8000); // Seq end - pixels_pattern[++pos] = 0 | (0x8000); // Seq end + pixels_pattern[pos++] = 0 | (0x8000); // Seq end + pixels_pattern[pos++] = 0 | (0x8000); // Seq end NRF_PWM_Type* pwm = NRF_PWM2; @@ -293,3 +346,40 @@ void neopixel_write (uint8_t *pixels) } #endif +#if defined(LED_RGB_RED_PIN) && defined(LED_RGB_GREEN_PIN) && defined(LED_RGB_BLUE_PIN) + +#ifdef LED_SECONDARY_PIN +#error "Cannot use secondary LED at the same time as an RGB status LED." +#endif + +#define LED_RGB_RED 1 +#define LED_RGB_BLUE 2 +#define LED_RGB_GREEN 3 + +void neopixel_init(void) +{ + led_pwm_init(LED_RGB_RED, LED_RGB_RED_PIN); + led_pwm_init(LED_RGB_GREEN, LED_RGB_GREEN_PIN); + led_pwm_init(LED_RGB_BLUE, LED_RGB_BLUE_PIN); +} + +void neopixel_teardown(void) +{ + uint8_t grb[3] = { 0, 0, 0 }; + neopixel_write(grb); +} + +// write 3 bytes color to a built-in neopixel +void neopixel_write (uint8_t *pixels) +{ + led_pwm_duty_cycle(LED_RGB_RED, pixels[2]); + led_pwm_duty_cycle(LED_RGB_GREEN, pixels[1]); + led_pwm_duty_cycle(LED_RGB_BLUE, pixels[0]); +} +#endif + +#if !LED_NEOPIXEL && !defined(LED_RGB_RED) +void neopixel_write(uint8_t* pixels) { + (void) pixels; +} +#endif diff --git a/src/boards.h b/src/boards.h index b81bf6e..5266ac5 100644 --- a/src/boards.h +++ b/src/boards.h @@ -25,15 +25,32 @@ #include "boards/pca10056.h" #elif defined BOARD_PCA10059 #include "boards/pca10059.h" +#elif defined BOARD_PARTICLE_ARGON +#include "boards/particle_argon.h" +#elif defined BOARD_PARTICLE_BORON +#include "boards/particle_boron.h" +#elif defined BOARD_PARTICLE_XENON +#include "boards/particle_xenon.h" #else #error No boards defined #endif +#ifndef BUTTON_DFU #define BUTTON_DFU BUTTON_1 +#endif +#ifndef BUTTON_FRESET #define BUTTON_FRESET BUTTON_2 +#endif -#define LED_RED LED_1 -#define LED_BLUE LED_2 +// The primary LED is usually Red but not in all cases. +#define LED_PRIMARY 0 +// The secondary LED, when available, is usually blue. +#define LED_SECONDARY 1 + +// The internal +#ifndef BOARD_RGB_BRIGHTNESS +#define BOARD_RGB_BRIGHTNESS 0x101010 +#endif // Helper function #define memclr(buffer, size) memset(buffer, 0, size) @@ -50,29 +67,24 @@ void board_teardown(void); #define bit(b) (1UL << (b)) -static inline void led_control(uint32_t pin, bool state) -{ - nrf_gpio_pin_write(pin, state ? LED_STATE_ON : (1-LED_STATE_ON)); -} +#define STATE_BOOTLOADER_STARTED 0 +#define STATE_USB_MOUNTED 1 +#define STATE_USB_UNMOUNTED 2 +#define STATE_FACTORY_RESET_STARTED 3 +#define STATE_FACTORY_RESET_FINISHED 4 +#define STATE_WRITING_STARTED 5 +#define STATE_WRITING_FINISHED 6 +#define STATE_BLE_CONNECTED 7 +#define STATE_BLE_DISCONNECTED 8 -static inline void led_on(uint32_t pin) -{ - led_control(pin, true); -} +void led_pwm_init(uint32_t led_index, uint32_t led_pin); +void led_pwm_teardown(void); +void led_pwm_disable(uint32_t led_index); +void led_pwm_enable(uint32_t led_index); +void led_state(uint32_t state); +void led_tick(void); -static inline void led_off(uint32_t pin) -{ - led_control(pin, false); -} - -void led_pwm_init(uint32_t led_pin); -void led_pwm_teardown(uint32_t led_pin); -void led_pwm_disable(uint32_t led_pin); -void led_pwm_enable(uint32_t led_pin); - -void led_red_blink_fast(bool enable); - -#ifdef LED_NEOPIXEL +#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) void neopixel_write(uint8_t *pixels); #endif diff --git a/src/boards/feather_nrf52832.h b/src/boards/feather_nrf52832.h index 415c086..05d8798 100644 --- a/src/boards/feather_nrf52832.h +++ b/src/boards/feather_nrf52832.h @@ -41,8 +41,8 @@ /* LED *------------------------------------------------------------------*/ #define LEDS_NUMBER 2 -#define LED_1 17 -#define LED_2 19 +#define LED_PRIMARY_PIN 17 // Red +#define LED_SECODARY_PIN 19 // Blue #define LED_STATE_ON 1 /*------------------------------------------------------------------*/ @@ -66,4 +66,6 @@ #define DIS_MANUFACTURER "Adafruit Industries" #define DIS_MODEL "Bluefruit Feather nRF52832" +#define PRODUCT_NAME "Adafruit Bluefruit Feather nRF52832" + #endif // _FEATHER52832_H diff --git a/src/boards/feather_nrf52840_express.h b/src/boards/feather_nrf52840_express.h index ddc83d0..7859f0d 100644 --- a/src/boards/feather_nrf52840_express.h +++ b/src/boards/feather_nrf52840_express.h @@ -43,9 +43,10 @@ /* LED *------------------------------------------------------------------*/ #define LEDS_NUMBER 2 -#define LED_1 _PINNUM(1, 15) -#define LED_2 _PINNUM(1, 10) +#define LED_PRIMARY_PIN _PINNUM(1, 15) +#define LED_SECONDARY_PIN _PINNUM(1, 10) #define LED_NEOPIXEL 16 +#define BOARD_RGB_BRIGHTNESS 0x040404 #define LED_STATE_ON 1 /*------------------------------------------------------------------*/ @@ -65,8 +66,12 @@ #define RTS_PIN_NUMBER 5 #define HWFC false +#define OUTPUT_500HZ_PIN _PINNUM(0, 05) // A1 + // Used as model string in OTA mode #define DIS_MANUFACTURER "Adafruit Industries" #define DIS_MODEL "Bluefruit Feather nRF52840 Express" +#define PRODUCT_NAME "Adafruit Feather nRF52840 Express" + #endif // _FEATHER52840_H diff --git a/src/boards/particle_argon.h b/src/boards/particle_argon.h new file mode 100644 index 0000000..cc432d6 --- /dev/null +++ b/src/boards/particle_argon.h @@ -0,0 +1,77 @@ +/**************************************************************************/ +/*! + @file particle_boron.h + @author Scott Shawcroft + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Scott Shawcroft for Adafruit Industries (adafruit.com) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _PARTICLE_ARGON_H +#define _PARTICLE_ARGON_H + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +/*------------------------------------------------------------------*/ +/* LED + *------------------------------------------------------------------*/ +#define LEDS_NUMBER 2 +#define LED_RED _PINNUM(0, 13) +#define LED_BLUE _PINNUM(0, 15) +#define LED_STATE_ON 0 + +/*------------------------------------------------------------------*/ +/* BUTTON + *------------------------------------------------------------------*/ +#define BUTTONS_NUMBER 2 +#define BUTTON_DFU _PINNUM(0, 11) +#define BUTTON_FRESET _PINNUM(0, 03) // A0 +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +/*------------------------------------------------------------------*/ +/* UART + *------------------------------------------------------------------*/ +#define RX_PIN_NUMBER 8 +#define TX_PIN_NUMBER 6 +#define CTS_PIN_NUMBER 0 +#define RTS_PIN_NUMBER 0 +#define HWFC false + +// Used as model string in OTA mode +#define DIS_MANUFACTURER "Particle Industries" +#define DIS_MODEL "Argon" + +#define VOLUME_LABEL "ARGONBOOT " + +#define BOARD_ID "Particle-Argon-v1" + +#define INDEX_URL "https://www.particle.io/mesh/" + +#endif // _PARTICLE_ARGON_H diff --git a/src/boards/particle_boron.h b/src/boards/particle_boron.h new file mode 100644 index 0000000..aa5e545 --- /dev/null +++ b/src/boards/particle_boron.h @@ -0,0 +1,81 @@ +/**************************************************************************/ +/*! + @file particle_boron.h + @author Scott Shawcroft + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Scott Shawcroft for Adafruit Industries (adafruit.com) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _PARTICLE_BORON_H +#define _PARTICLE_BORON_H + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +/*------------------------------------------------------------------*/ +/* LED + *------------------------------------------------------------------*/ +#define LEDS_NUMBER 1 +#define LED_PRIMARY_PIN _PINNUM(1, 12) +#define LED_STATE_ON 0 + +#define LED_RGB_RED_PIN _PINNUM(0, 13) +#define LED_RGB_GREEN_PIN _PINNUM(0, 14) +#define LED_RGB_BLUE_PIN _PINNUM(0, 15) +/*------------------------------------------------------------------*/ +/* BUTTON + *------------------------------------------------------------------*/ +#define BUTTONS_NUMBER 2 +#define BUTTON_DFU _PINNUM(0, 11) +#define BUTTON_FRESET _PINNUM(0, 03) // A0 +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +/*------------------------------------------------------------------*/ +/* UART + *------------------------------------------------------------------*/ +#define RX_PIN_NUMBER 8 +#define TX_PIN_NUMBER 6 +#define CTS_PIN_NUMBER 0 +#define RTS_PIN_NUMBER 0 +#define HWFC false + +#define OUTPUT_500HZ_PIN _PINNUM(0, 04) // A1 + +// Used as model string in OTA mode +#define DIS_MANUFACTURER "Particle Industries" +#define DIS_MODEL "Boron" + +#define VOLUME_LABEL "BORONBOOT " + +#define BOARD_ID "Particle-Boron-v1" + +#define INDEX_URL "https://www.particle.io/mesh/" + +#endif // _PARTICLE_BORON_H diff --git a/src/boards/particle_xenon.h b/src/boards/particle_xenon.h new file mode 100644 index 0000000..8510dc1 --- /dev/null +++ b/src/boards/particle_xenon.h @@ -0,0 +1,77 @@ +/**************************************************************************/ +/*! + @file particle_boron.h + @author Scott Shawcroft + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Scott Shawcroft for Adafruit Industries (adafruit.com) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _PARTICLE_XENON_H +#define _PARTICLE_XENON_H + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +/*------------------------------------------------------------------*/ +/* LED + *------------------------------------------------------------------*/ +#define LEDS_NUMBER 2 +#define LED_RED _PINNUM(0, 13) +#define LED_BLUE _PINNUM(0, 15) +#define LED_STATE_ON 0 + +/*------------------------------------------------------------------*/ +/* BUTTON + *------------------------------------------------------------------*/ +#define BUTTONS_NUMBER 2 +#define BUTTON_DFU _PINNUM(0, 11) +#define BUTTON_FRESET _PINNUM(0, 03) // A0 +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +/*------------------------------------------------------------------*/ +/* UART + *------------------------------------------------------------------*/ +#define RX_PIN_NUMBER 8 +#define TX_PIN_NUMBER 6 +#define CTS_PIN_NUMBER 0 +#define RTS_PIN_NUMBER 0 +#define HWFC false + +// Used as model string in OTA mode +#define DIS_MANUFACTURER "Particle Industries" +#define DIS_MODEL "Xenon" + +#define VOLUME_LABEL "XENONBOOT " + +#define BOARD_ID "Particle-Xenon-v1" + +#define INDEX_URL "https://www.particle.io/mesh/" + +#endif // _PARTICLE_XENON_H diff --git a/src/boards/pca10056.h b/src/boards/pca10056.h index 9c05134..c49ba36 100644 --- a/src/boards/pca10056.h +++ b/src/boards/pca10056.h @@ -41,8 +41,8 @@ /* LED *------------------------------------------------------------------*/ #define LEDS_NUMBER 2 -#define LED_1 13 -#define LED_2 14 +#define LED_PRIMARY_PIN 13 +#define LED_SECONDARY_PIN 14 #define LED_STATE_ON 0 /*------------------------------------------------------------------*/ diff --git a/src/boards/pca10059.h b/src/boards/pca10059.h index 97b775c..cfa3cb3 100644 --- a/src/boards/pca10059.h +++ b/src/boards/pca10059.h @@ -40,12 +40,10 @@ /*------------------------------------------------------------------*/ /* LED *------------------------------------------------------------------*/ -#define LEDS_NUMBER 2 -// LED_RED -#define LED_1 6 -// LED_BLUE -#define LED_2 12 -#define LED_STATE_ON 0 +#define LEDS_NUMBER 2 +#define LED_PRIMARY_PIN 6 // Red +#define LED_SECONDARY_PIN 12 // Blue +#define LED_STATE_ON 0 /*------------------------------------------------------------------*/ /* BUTTON diff --git a/src/main.c b/src/main.c index 02be46c..d9c9bf5 100644 --- a/src/main.c +++ b/src/main.c @@ -170,12 +170,12 @@ int main(void) // When updating SoftDevice, bootloader will reset before swapping SD if (bootloader_dfu_sd_in_progress()) { - led_red_blink_fast(true); + led_state(STATE_WRITING_STARTED); APP_ERROR_CHECK( bootloader_dfu_sd_update_continue() ); APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() ); - led_red_blink_fast(false); + led_state(STATE_WRITING_FINISHED); } /*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/ @@ -209,18 +209,19 @@ int main(void) (*dbl_reset_mem) = 0; - if ( dfu_start || !valid_app ) + led_state(STATE_BOOTLOADER_STARTED); + + if ( dfu_start || !valid_app || true) { if ( _ota_dfu ) { - // Enable BLE if in OTA - led_pwm_init(LED_BLUE); - + led_state(STATE_BLE_DISCONNECTED); softdev_init(!sd_inited); sd_inited = true; } else { + led_state(STATE_USB_UNMOUNTED); // otherwise USB for Serial & UF2 usb_init(serial_only_dfu); } @@ -230,9 +231,6 @@ int main(void) if ( _ota_dfu ) { - led_pwm_teardown(LED_BLUE); - led_off(LED_BLUE); - sd_softdevice_disable(); }else { @@ -267,9 +265,7 @@ int main(void) // Perform factory reset to erase Application + Data void adafruit_factory_reset(void) { - // Blink fast RED and turn on BLUE when erasing - led_red_blink_fast(true); - led_on(LED_BLUE); + led_state(STATE_FACTORY_RESET_STARTED); // clear all App Data if any if ( DFU_APP_DATA_RESERVED ) @@ -281,8 +277,7 @@ void adafruit_factory_reset(void) nrf_nvmc_page_erase(DFU_BANK_0_REGION_START); // back to normal - led_red_blink_fast(false); - led_off(LED_BLUE); + led_state(STATE_FACTORY_RESET_FINISHED); } /** @@ -394,13 +389,12 @@ uint32_t proc_ble(void) { case BLE_GAP_EVT_CONNECTED: _ota_connected = true; - led_pwm_disable(LED_BLUE); - led_on(LED_BLUE); + led_state(STATE_BLE_CONNECTED); break; case BLE_GAP_EVT_DISCONNECTED: _ota_connected = false; - led_pwm_enable(LED_BLUE); // LED Blink + led_state(STATE_BLE_DISCONNECTED); break; default: break; @@ -455,5 +449,3 @@ void SD_EVT_IRQHandler(void) // Use App Scheduler to defer handling code in non-isr context app_sched_event_put(NULL, 0, ada_sd_task); } - - diff --git a/src/usb/uf2/ghostfat.c b/src/usb/uf2/ghostfat.c index 329c6e2..bea65b6 100644 --- a/src/usb/uf2/ghostfat.c +++ b/src/usb/uf2/ghostfat.c @@ -235,7 +235,7 @@ void read_block(uint32_t block_no, uint8_t *data) { /** uf2 upgrade complete -> inform bootloader to update setting and reset */ static void uf2_write_complete(uint32_t numBlocks) { - led_red_blink_fast(false); + led_state(STATE_WRITING_FINISHED); dfu_update_status_t update_status; @@ -285,9 +285,9 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *stat static bool first_write = true; if ( first_write ) { first_write = false; - led_red_blink_fast(true); + led_state(STATE_WRITING_STARTED); } - + flash_nrf5x_write(bl->targetAddr, bl->data, bl->payloadSize, true); } @@ -318,4 +318,3 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *stat return 512; } - diff --git a/src/usb/uf2/uf2cfg.h b/src/usb/uf2/uf2cfg.h index d9ef358..548ebf4 100644 --- a/src/usb/uf2/uf2cfg.h +++ b/src/usb/uf2/uf2cfg.h @@ -1,17 +1,27 @@ +#include "boards.h" + #define UF2_VERSION "1.00" -#ifdef BOARD_PCA10056 +#ifndef PRODUCT_NAME #define PRODUCT_NAME DIS_MODEL -#else - #define PRODUCT_NAME "Adafruit " DIS_MODEL #endif +#ifndef BOARD_ID #define BOARD_ID "NRF52-Bluefruit-v0" -#define INDEX_URL "https://www.adafruit.com/product/0000" +#endif + +#ifndef INDEX_URL +#define INDEX_URL "https://www.adafruit.com/" +#endif + #define BOOTLOADER_ID MK_DIS_FIRMWARE #define UF2_NUM_BLOCKS 8000 // at least 4,1 MB for FAT16 + +#ifndef VOLUME_LABEL #define VOLUME_LABEL "NRF52BOOT " +#endif + #define FLASH_SIZE (USER_FLASH_END-USER_FLASH_START) // Max flash size // Only allow to write application TODO dynamic depending on SD size diff --git a/src/usb/usb.c b/src/usb/usb.c index fe27f57..f49e6c0 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -157,17 +157,10 @@ void usb_teardown(void) //--------------------------------------------------------------------+ void tud_mount_cb(void) { -#ifdef LED_NEOPIXEL - uint8_t grb[3] = { 32, 0, 0 }; - neopixel_write(grb); -#endif + led_state(STATE_USB_MOUNTED); } void tud_umount_cb(void) { -#ifdef LED_NEOPIXEL - uint8_t grb[3] = { 0, 32, 0 }; - neopixel_write(grb); -#endif + led_state(STATE_USB_UNMOUNTED); } -