Rework LED flashing and add Particle's boards

This commit is contained in:
Scott Shawcroft 2018-12-04 13:45:55 -08:00
parent f30199f503
commit 2ece2daf90
No known key found for this signature in database
GPG Key ID: FD0EDC4B6C53CA59
17 changed files with 501 additions and 166 deletions

View File

@ -53,9 +53,7 @@ endif
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
PROGFILES = C:/Program Files (x86) PROGFILES = C:/Program Files (x86)
GNU_INSTALL_ROOT = $(PROGFILES)/GNU Tools ARM Embedded/7 2018-q2-update GNU_INSTALL_ROOT = $(PROGFILES)/GNU Tools ARM Embedded/7 2018-q2-update/bin/
else
GNU_INSTALL_ROOT = /usr
endif endif
MK := mkdir MK := mkdir
@ -70,14 +68,14 @@ endif
GNU_PREFIX = arm-none-eabi GNU_PREFIX = arm-none-eabi
# Toolchain commands # Toolchain commands
CC := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc' CC := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-gcc'
AS := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as' AS := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-as'
AR := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar' -r AR := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ar' -r
LD := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld' LD := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ld'
NM := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm' NM := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-nm'
OBJDUMP := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump' OBJDUMP := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objdump'
OBJCOPY := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy' OBJCOPY := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objcopy'
SIZE := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size' SIZE := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-size'
#function for removing duplicates in a list #function for removing duplicates in a list
remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1)))) 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)))) 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)) IS_NRF52840 = $(filter $(BOARD),$(NRF52840_BOARDLIST))
ifeq ($(filter $(MAKECMDGOALS),all-board all-release help),) ifeq ($(filter $(MAKECMDGOALS),all-board all-release help),)
@ -370,7 +368,7 @@ all-board:
all-release: all-release:
$(call _make_all_board,clean all release) $(call _make_all_board,clean all release)
help: help:
@echo To flash (with jlink) a pre-built binary with a specific version to a board @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 @echo $$ make BOARD=feather_nrf52840_express VERSION=6.1.1r0 flash

View File

@ -136,6 +136,8 @@ static void wait_for_events(void)
} }
#endif #endif
led_tick();
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) )
@ -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) else if (update_status.status_code == DFU_UPDATE_SD_COMPLETE)
{ {
settings.bank_0_crc = update_status.app_crc; settings.bank_0_crc = update_status.app_crc;
settings.bank_0_size = update_status.sd_size + settings.bank_0_size = update_status.sd_size +
update_status.bl_size + update_status.bl_size +
update_status.app_size; update_status.app_size;
settings.bank_0 = BANK_VALID_SD; settings.bank_0 = BANK_VALID_SD;
settings.bank_1 = BANK_INVALID_APP; 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; uint32_t err_code;
// Clear swap if banked update is used. // Clear swap if banked update is used.
err_code = dfu_init(); err_code = dfu_init();
VERIFY_SUCCESS(err_code); VERIFY_SUCCESS(err_code);
if ( ota ) 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->app_image_size = p_bootloader_settings->app_image_size;
p_settings->sd_image_start = p_bootloader_settings->sd_image_start; p_settings->sd_image_start = p_bootloader_settings->sd_image_start;
} }

View File

@ -589,7 +589,7 @@ static void on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
break; break;
case BLE_DFU_PACKET_WRITE: case BLE_DFU_PACKET_WRITE:
led_red_blink_fast(true); led_state(STATE_WRITING_STARTED);
on_dfu_pkt_write(p_dfu, p_evt); on_dfu_pkt_write(p_dfu, p_evt);
break; break;
@ -741,6 +741,7 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
case BLE_GAP_EVT_CONNECTED: case BLE_GAP_EVT_CONNECTED:
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
m_is_advertising = false; m_is_advertising = false;
led_state(STATE_BLE_CONNECTED);
break; break;
case BLE_GAP_EVT_DISCONNECTED: 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; 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,
&sys_attr_len, &sys_attr_len,
BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS); BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);

View File

@ -106,7 +106,7 @@ static uint32_t data_queue_element_free(uint8_t element_index)
uint32_t retval; uint32_t retval;
retval = NRF_ERROR_INVALID_PARAM; retval = NRF_ERROR_INVALID_PARAM;
if (MAX_BUFFERS > element_index) if (MAX_BUFFERS > element_index)
{ {
p_data = (uint8_t *)DATA_QUEUE_ELEMENT_GET_PDATA(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; uint32_t index;
retval = NRF_ERROR_NO_MEM; retval = NRF_ERROR_NO_MEM;
if (INVALID_PACKET == packet_type) if (INVALID_PACKET == packet_type)
{ {
retval = NRF_ERROR_INVALID_PARAM; retval = NRF_ERROR_INVALID_PARAM;
@ -216,7 +216,7 @@ static void process_dfu_packet(void * p_event_data, uint16_t event_size)
break; break;
case START_PACKET: case START_PACKET:
packet->params.start_packet = packet->params.start_packet =
(dfu_start_packet_t*)packet->params.data_packet.p_data_packet; (dfu_start_packet_t*)packet->params.data_packet.p_data_packet;
retval = dfu_start_pkt_handle(packet); retval = dfu_start_pkt_handle(packet);
APP_ERROR_CHECK(retval); 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(); retval = dfu_init_pkt_complete();
APP_ERROR_CHECK(retval); APP_ERROR_CHECK(retval);
led_red_blink_fast(true); led_state(STATE_WRITING_STARTED);
break; break;
case STOP_DATA_PACKET: case STOP_DATA_PACKET:
(void)dfu_image_validate(); (void)dfu_image_validate();
(void)dfu_image_activate(); (void)dfu_image_activate();
led_red_blink_fast(false); led_state(STATE_WRITING_FINISHED);
// Break the loop by returning. // Break the loop by returning.
return; 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); retval = app_sched_event_put(NULL, 0, process_dfu_packet);
} }
} }
if (p_rpc_cmd_buffer != NULL && NRF_SUCCESS != retval) if (p_rpc_cmd_buffer != NULL && NRF_SUCCESS != retval)
{ {
// Free the packet that could not be processed. // Free the packet that could not be processed.
@ -308,7 +308,6 @@ uint32_t dfu_transport_serial_close(void)
{ {
// Remove all buffered packets. // Remove all buffered packets.
data_queue_flush(); data_queue_flush();
return hci_transport_close(); return hci_transport_close();
} }

View File

@ -45,20 +45,11 @@
#define SCHED_MAX_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Maximum size of scheduler events. */ #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. */ #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 -------------// //------------- IMPLEMENTATION -------------//
#ifdef OUTPUT_500HZ_PIN
void init_clock_pwm(uint32_t pin);
void clock_pwm_teardown(void);
#endif
void board_init(void) void board_init(void)
{ {
@ -73,22 +64,16 @@ void board_init(void)
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
// 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 // 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 // use neopixel for use enumeration
#ifdef LED_NEOPIXEL #if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
extern void neopixel_init(void); extern void neopixel_init(void);
neopixel_init(); neopixel_init();
uint8_t grb[3] = { 0, 32, 0 };
neopixel_write(grb);
#endif #endif
// Init scheduler // Init scheduler
@ -100,17 +85,13 @@ void board_init(void)
void board_teardown(void) void board_teardown(void)
{ {
// Disable and reset PWM for LED // Disable and reset PWM for LEDs
led_pwm_teardown(LED_RED); led_pwm_teardown();
#ifdef LED_NEOPIXEL #if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
extern void neopixel_teardown(void); extern void neopixel_teardown(void);
neopixel_teardown(); neopixel_teardown();
#endif #endif
led_off(LED_BLUE);
led_off(LED_RED);
// Button // Button
// Stop RTC1 used by app_timer // Stop RTC1 used by app_timer
@ -146,58 +127,129 @@ void pwm_teardown(NRF_PWM_Type* pwm )
pwm->SEQ[0].CNT = 0; pwm->SEQ[0].CNT = 0;
} }
void led_pwm_init(uint32_t led_pin) static uint16_t led_duty_cycles[PWM0_CH_NUM];
{
NRF_PWM_Type* pwm = (led_pin == LED_RED) ? NRF_PWM0 : NRF_PWM1;
pwm->MODE = PWM_MODE_UPDOWN_UpAndDown; #if LEDS_NUMBER > PWM0_CH_NUM
pwm->COUNTERTOP = PWM_MAXCOUNT; #error "Only " PWM0_CH_NUM " concurrent status LEDs are supported."
pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_128; #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->DECODER = PWM_DECODER_LOAD_Individual;
pwm->LOOP = 0; pwm->LOOP = 0;
pwm->SEQ[0].PTR = (uint32_t) (led_pin == LED_RED ? _pwm_red_seq : _pwm_blue_seq); pwm->SEQ[0].PTR = (uint32_t) (led_duty_cycles);
pwm->SEQ[0].CNT = PWM_CHANNEL_NUM; // default mode is Individual --> count must be 4 pwm->SEQ[0].CNT = 4; // default mode is Individual --> count must be 4
pwm->SEQ[0].REFRESH = 0; pwm->SEQ[0].REFRESH = 0;
pwm->SEQ[0].ENDDELAY = 0; pwm->SEQ[0].ENDDELAY = 0;
pwm->LOOP = 0;
pwm->PSEL.OUT[0] = led_pin;
pwm->ENABLE = 1;
pwm->TASKS_SEQSTART[0] = 1; 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; led_duty_cycles[led_index] = duty_cycle;
nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_SEQEND0);
pwm->TASKS_SEQSTART[0] = 0; nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0);
pwm->ENABLE = 0;
} }
void led_pwm_enable(uint32_t led_pin) static uint32_t primary_cycle_length;
{ #ifdef LED_SECONDARY_PIN
NRF_PWM_Type* pwm = (led_pin == LED_RED) ? NRF_PWM0 : NRF_PWM1; static uint32_t secondary_cycle_length;
#endif
void led_tick() {
uint32_t millis = tusb_hal_millis();
pwm->ENABLE = 1; uint32_t cycle = millis % primary_cycle_length;
pwm->TASKS_SEQSTART[0] = 1; 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
} }
static uint32_t rgb_color;
void led_red_blink_fast(bool enable) static bool temp_color_active = false;
void led_state(uint32_t state)
{ {
if ( enable ) uint32_t new_rgb_color = rgb_color;
{ uint32_t temp_color = 0;
NRF_PWM0->MODE = PWM_MODE_UPDOWN_Up; switch (state) {
}else case STATE_USB_MOUNTED:
{ new_rgb_color = 0x00ff00;
NRF_PWM0->MODE = PWM_MODE_UPDOWN_UpAndDown; 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 #if LED_NEOPIXEL
@ -267,10 +319,11 @@ void neopixel_teardown(void)
// write 3 bytes color to a built-in neopixel // write 3 bytes color to a built-in neopixel
void neopixel_write (uint8_t *pixels) void neopixel_write (uint8_t *pixels)
{ {
uint8_t grb[NEO_NUMBYTE] = {pixels[1], pixels[2], pixels[0]};
uint16_t pos = 0; // bit position uint16_t pos = 0; // bit position
for ( uint16_t n = 0; n < NEO_NUMBYTE; n++ ) 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 ) 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 // 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; NRF_PWM_Type* pwm = NRF_PWM2;
@ -293,3 +346,40 @@ void neopixel_write (uint8_t *pixels)
} }
#endif #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

View File

@ -25,15 +25,32 @@
#include "boards/pca10056.h" #include "boards/pca10056.h"
#elif defined BOARD_PCA10059 #elif defined BOARD_PCA10059
#include "boards/pca10059.h" #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 #else
#error No boards defined #error No boards defined
#endif #endif
#ifndef BUTTON_DFU
#define BUTTON_DFU BUTTON_1 #define BUTTON_DFU BUTTON_1
#endif
#ifndef BUTTON_FRESET
#define BUTTON_FRESET BUTTON_2 #define BUTTON_FRESET BUTTON_2
#endif
#define LED_RED LED_1 // The primary LED is usually Red but not in all cases.
#define LED_BLUE LED_2 #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 // Helper function
#define memclr(buffer, size) memset(buffer, 0, size) #define memclr(buffer, size) memset(buffer, 0, size)
@ -50,29 +67,24 @@ void board_teardown(void);
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
static inline void led_control(uint32_t pin, bool state) #define STATE_BOOTLOADER_STARTED 0
{ #define STATE_USB_MOUNTED 1
nrf_gpio_pin_write(pin, state ? LED_STATE_ON : (1-LED_STATE_ON)); #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) void led_pwm_init(uint32_t led_index, uint32_t led_pin);
{ void led_pwm_teardown(void);
led_control(pin, true); 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) #if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_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
void neopixel_write(uint8_t *pixels); void neopixel_write(uint8_t *pixels);
#endif #endif

View File

@ -41,8 +41,8 @@
/* LED /* LED
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#define LEDS_NUMBER 2 #define LEDS_NUMBER 2
#define LED_1 17 #define LED_PRIMARY_PIN 17 // Red
#define LED_2 19 #define LED_SECODARY_PIN 19 // Blue
#define LED_STATE_ON 1 #define LED_STATE_ON 1
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
@ -66,4 +66,6 @@
#define DIS_MANUFACTURER "Adafruit Industries" #define DIS_MANUFACTURER "Adafruit Industries"
#define DIS_MODEL "Bluefruit Feather nRF52832" #define DIS_MODEL "Bluefruit Feather nRF52832"
#define PRODUCT_NAME "Adafruit Bluefruit Feather nRF52832"
#endif // _FEATHER52832_H #endif // _FEATHER52832_H

View File

@ -43,9 +43,10 @@
/* LED /* LED
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#define LEDS_NUMBER 2 #define LEDS_NUMBER 2
#define LED_1 _PINNUM(1, 15) #define LED_PRIMARY_PIN _PINNUM(1, 15)
#define LED_2 _PINNUM(1, 10) #define LED_SECONDARY_PIN _PINNUM(1, 10)
#define LED_NEOPIXEL 16 #define LED_NEOPIXEL 16
#define BOARD_RGB_BRIGHTNESS 0x040404
#define LED_STATE_ON 1 #define LED_STATE_ON 1
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
@ -65,8 +66,12 @@
#define RTS_PIN_NUMBER 5 #define RTS_PIN_NUMBER 5
#define HWFC false #define HWFC false
#define OUTPUT_500HZ_PIN _PINNUM(0, 05) // A1
// Used as model string in OTA mode // Used as model string in OTA mode
#define DIS_MANUFACTURER "Adafruit Industries" #define DIS_MANUFACTURER "Adafruit Industries"
#define DIS_MODEL "Bluefruit Feather nRF52840 Express" #define DIS_MODEL "Bluefruit Feather nRF52840 Express"
#define PRODUCT_NAME "Adafruit Feather nRF52840 Express"
#endif // _FEATHER52840_H #endif // _FEATHER52840_H

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -41,8 +41,8 @@
/* LED /* LED
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#define LEDS_NUMBER 2 #define LEDS_NUMBER 2
#define LED_1 13 #define LED_PRIMARY_PIN 13
#define LED_2 14 #define LED_SECONDARY_PIN 14
#define LED_STATE_ON 0 #define LED_STATE_ON 0
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/

View File

@ -40,12 +40,10 @@
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* LED /* LED
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#define LEDS_NUMBER 2 #define LEDS_NUMBER 2
// LED_RED #define LED_PRIMARY_PIN 6 // Red
#define LED_1 6 #define LED_SECONDARY_PIN 12 // Blue
// LED_BLUE #define LED_STATE_ON 0
#define LED_2 12
#define LED_STATE_ON 0
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* BUTTON /* BUTTON

View File

@ -170,12 +170,12 @@ int main(void)
// When updating SoftDevice, bootloader will reset before swapping SD // When updating SoftDevice, bootloader will reset before swapping SD
if (bootloader_dfu_sd_in_progress()) 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_continue() );
APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() ); 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) -------------*/ /*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/
@ -209,18 +209,19 @@ int main(void)
(*dbl_reset_mem) = 0; (*dbl_reset_mem) = 0;
if ( dfu_start || !valid_app ) led_state(STATE_BOOTLOADER_STARTED);
if ( dfu_start || !valid_app || true)
{ {
if ( _ota_dfu ) if ( _ota_dfu )
{ {
// Enable BLE if in OTA led_state(STATE_BLE_DISCONNECTED);
led_pwm_init(LED_BLUE);
softdev_init(!sd_inited); softdev_init(!sd_inited);
sd_inited = true; sd_inited = true;
} }
else else
{ {
led_state(STATE_USB_UNMOUNTED);
// otherwise USB for Serial & UF2 // otherwise USB for Serial & UF2
usb_init(serial_only_dfu); usb_init(serial_only_dfu);
} }
@ -230,9 +231,6 @@ int main(void)
if ( _ota_dfu ) if ( _ota_dfu )
{ {
led_pwm_teardown(LED_BLUE);
led_off(LED_BLUE);
sd_softdevice_disable(); sd_softdevice_disable();
}else }else
{ {
@ -267,9 +265,7 @@ int main(void)
// Perform factory reset to erase Application + Data // Perform factory reset to erase Application + Data
void adafruit_factory_reset(void) void adafruit_factory_reset(void)
{ {
// Blink fast RED and turn on BLUE when erasing led_state(STATE_FACTORY_RESET_STARTED);
led_red_blink_fast(true);
led_on(LED_BLUE);
// clear all App Data if any // clear all App Data if any
if ( DFU_APP_DATA_RESERVED ) if ( DFU_APP_DATA_RESERVED )
@ -281,8 +277,7 @@ void adafruit_factory_reset(void)
nrf_nvmc_page_erase(DFU_BANK_0_REGION_START); nrf_nvmc_page_erase(DFU_BANK_0_REGION_START);
// back to normal // back to normal
led_red_blink_fast(false); led_state(STATE_FACTORY_RESET_FINISHED);
led_off(LED_BLUE);
} }
/** /**
@ -394,13 +389,12 @@ uint32_t proc_ble(void)
{ {
case BLE_GAP_EVT_CONNECTED: case BLE_GAP_EVT_CONNECTED:
_ota_connected = true; _ota_connected = true;
led_pwm_disable(LED_BLUE); led_state(STATE_BLE_CONNECTED);
led_on(LED_BLUE);
break; break;
case BLE_GAP_EVT_DISCONNECTED: case BLE_GAP_EVT_DISCONNECTED:
_ota_connected = false; _ota_connected = false;
led_pwm_enable(LED_BLUE); // LED Blink led_state(STATE_BLE_DISCONNECTED);
break; break;
default: break; default: break;
@ -455,5 +449,3 @@ void SD_EVT_IRQHandler(void)
// Use App Scheduler to defer handling code in non-isr context // Use App Scheduler to defer handling code in non-isr context
app_sched_event_put(NULL, 0, ada_sd_task); app_sched_event_put(NULL, 0, ada_sd_task);
} }

View File

@ -235,7 +235,7 @@ void read_block(uint32_t block_no, uint8_t *data) {
/** uf2 upgrade complete -> inform bootloader to update setting and reset */ /** uf2 upgrade complete -> inform bootloader to update setting and reset */
static void uf2_write_complete(uint32_t numBlocks) static void uf2_write_complete(uint32_t numBlocks)
{ {
led_red_blink_fast(false); led_state(STATE_WRITING_FINISHED);
dfu_update_status_t update_status; 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; static bool first_write = true;
if ( first_write ) { if ( first_write ) {
first_write = false; first_write = false;
led_red_blink_fast(true); led_state(STATE_WRITING_STARTED);
} }
flash_nrf5x_write(bl->targetAddr, bl->data, bl->payloadSize, true); 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; return 512;
} }

View File

@ -1,17 +1,27 @@
#include "boards.h"
#define UF2_VERSION "1.00" #define UF2_VERSION "1.00"
#ifdef BOARD_PCA10056 #ifndef PRODUCT_NAME
#define PRODUCT_NAME DIS_MODEL #define PRODUCT_NAME DIS_MODEL
#else
#define PRODUCT_NAME "Adafruit " DIS_MODEL
#endif #endif
#ifndef BOARD_ID
#define BOARD_ID "NRF52-Bluefruit-v0" #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 BOOTLOADER_ID MK_DIS_FIRMWARE
#define UF2_NUM_BLOCKS 8000 // at least 4,1 MB for FAT16 #define UF2_NUM_BLOCKS 8000 // at least 4,1 MB for FAT16
#ifndef VOLUME_LABEL
#define VOLUME_LABEL "NRF52BOOT " #define VOLUME_LABEL "NRF52BOOT "
#endif
#define FLASH_SIZE (USER_FLASH_END-USER_FLASH_START) // Max flash size #define FLASH_SIZE (USER_FLASH_END-USER_FLASH_START) // Max flash size
// Only allow to write application TODO dynamic depending on SD size // Only allow to write application TODO dynamic depending on SD size

View File

@ -157,17 +157,10 @@ void usb_teardown(void)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void tud_mount_cb(void) void tud_mount_cb(void)
{ {
#ifdef LED_NEOPIXEL led_state(STATE_USB_MOUNTED);
uint8_t grb[3] = { 32, 0, 0 };
neopixel_write(grb);
#endif
} }
void tud_umount_cb(void) void tud_umount_cb(void)
{ {
#ifdef LED_NEOPIXEL led_state(STATE_USB_UNMOUNTED);
uint8_t grb[3] = { 0, 32, 0 };
neopixel_write(grb);
#endif
} }