mirror of
https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX.git
synced 2026-10-25 06:13:20 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
101a54da10 | ||
|
|
e81391f395 | ||
|
|
eaaf5f8e84 | ||
|
|
1c85a7a5be | ||
|
|
f5a1947974 | ||
|
|
66db5aeda3 | ||
|
|
36a1f428dd |
No files matched your search
@@ -22,6 +22,7 @@ jobs:
|
||||
- 'feather_nrf52833_express'
|
||||
- 'feather_nrf52840_express'
|
||||
- 'feather_nrf52840_sense'
|
||||
- 'feather_nrf52840_sense_tft'
|
||||
- 'itsybitsy_nrf52840_express'
|
||||
- 'metro_nrf52840_express'
|
||||
- 'ledglasses_nrf52840'
|
||||
@@ -67,13 +68,13 @@ jobs:
|
||||
uses: actions/setup-python@v3
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Checkout linkermap
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: hathach/linkermap
|
||||
path: linkermap
|
||||
@@ -85,7 +86,7 @@ jobs:
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
pip3 install adafruit-nrfutil uritemplate requests intelhex
|
||||
pip3 install adafruit-nrfutil uritemplate requests intelhex setuptools
|
||||
pip3 install linkermap/
|
||||
|
||||
- name: Build
|
||||
|
||||
+162
-184
@@ -38,35 +38,29 @@
|
||||
#define SCHED_QUEUE_SIZE 30 /**< Maximum number of events in the scheduler queue. */
|
||||
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
|
||||
void neopixel_init(void);
|
||||
void neopixel_write(uint8_t *pixels);
|
||||
void neopixel_teardown(void);
|
||||
void neopixel_init(void);
|
||||
void neopixel_write(uint8_t* pixels);
|
||||
void neopixel_teardown(void);
|
||||
#endif
|
||||
|
||||
//------------- IMPLEMENTATION -------------//
|
||||
void button_init(uint32_t pin)
|
||||
{
|
||||
if ( BUTTON_PULL == NRF_GPIO_PIN_PULLDOWN )
|
||||
{
|
||||
void button_init(uint32_t pin) {
|
||||
if (BUTTON_PULL == NRF_GPIO_PIN_PULLDOWN) {
|
||||
nrf_gpio_cfg_sense_input(pin, BUTTON_PULL, NRF_GPIO_PIN_SENSE_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
nrf_gpio_cfg_sense_input(pin, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
bool button_pressed(uint32_t pin)
|
||||
{
|
||||
bool button_pressed(uint32_t pin) {
|
||||
uint32_t const active_state = (BUTTON_PULL == NRF_GPIO_PIN_PULLDOWN ? 1 : 0);
|
||||
return nrf_gpio_pin_read(pin) == active_state;
|
||||
}
|
||||
|
||||
// This is declared so that a board specific init can be called from here.
|
||||
void __attribute__((weak)) board_init2(void) { }
|
||||
void __attribute__((weak)) board_init2(void) {}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
void board_init(void) {
|
||||
// stop LF clock just in case we jump from application without reset
|
||||
NRF_CLOCK->TASKS_LFCLKSTOP = 1UL;
|
||||
|
||||
@@ -85,8 +79,14 @@ void board_init(void)
|
||||
led_pwm_init(LED_SECONDARY, LED_SECONDARY_PIN);
|
||||
#endif
|
||||
#endif
|
||||
// use neopixel for use enumeration
|
||||
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
|
||||
// use neopixel for use enumeration
|
||||
#ifdef NEOPIXEL_POWER_PIN
|
||||
nrf_gpio_cfg_output(NEOPIXEL_POWER_PIN);
|
||||
nrf_gpio_pin_write(NEOPIXEL_POWER_PIN, 1);
|
||||
#endif
|
||||
|
||||
neopixel_init();
|
||||
#endif
|
||||
|
||||
@@ -99,23 +99,21 @@ void board_init(void)
|
||||
// Make sure any custom inits are performed
|
||||
board_init2();
|
||||
|
||||
// When board is supplied on VDDH (and not VDD), this specifies what voltage the GPIO should run at
|
||||
// and what voltage is output at VDD. The default (0xffffffff) is 1.8V; typically you'll want
|
||||
// #define UICR_REGOUT0_VALUE UICR_REGOUT0_VOUT_3V3
|
||||
// in board.h when using that power configuration.
|
||||
// When board is supplied on VDDH (and not VDD), this specifies what voltage the GPIO should run at
|
||||
// and what voltage is output at VDD. The default (0xffffffff) is 1.8V; typically you'll want
|
||||
// #define UICR_REGOUT0_VALUE UICR_REGOUT0_VOUT_3V3
|
||||
// in board.h when using that power configuration.
|
||||
#ifdef UICR_REGOUT0_VALUE
|
||||
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) !=
|
||||
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos))
|
||||
{
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
|
||||
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos);
|
||||
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != (UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos)){
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
|
||||
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos);
|
||||
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
|
||||
NVIC_SystemReset();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -127,14 +125,13 @@ void board_init(void)
|
||||
|
||||
// Configure Systick for led blinky
|
||||
NVIC_SetPriority(SysTick_IRQn, 7);
|
||||
SysTick_Config(SystemCoreClock/1000);
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
}
|
||||
|
||||
// Actions at the end of board_teardown.
|
||||
void __attribute__((weak)) board_teardown2(void) { }
|
||||
void __attribute__((weak)) board_teardown2(void) {}
|
||||
|
||||
void board_teardown(void)
|
||||
{
|
||||
void board_teardown(void) {
|
||||
// Disable systick, turn off LEDs
|
||||
SysTick->CTRL = 0;
|
||||
|
||||
@@ -149,9 +146,9 @@ void board_teardown(void)
|
||||
|
||||
// Stop RTC1 used by app_timer
|
||||
NVIC_DisableIRQ(RTC1_IRQn);
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
|
||||
NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
|
||||
NRF_RTC1->TASKS_STOP = 1;
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
|
||||
NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
|
||||
NRF_RTC1->TASKS_STOP = 1;
|
||||
NRF_RTC1->TASKS_CLEAR = 1;
|
||||
|
||||
// Stop LF clock
|
||||
@@ -159,8 +156,7 @@ void board_teardown(void)
|
||||
|
||||
// make sure all pins are back in reset state
|
||||
// NUMBER_OF_PINS is defined in nrf_gpio.h
|
||||
for (int i = 0; i < NUMBER_OF_PINS; ++i)
|
||||
{
|
||||
for (int i = 0; i < NUMBER_OF_PINS; ++i) {
|
||||
nrf_gpio_cfg_default(i);
|
||||
}
|
||||
|
||||
@@ -169,42 +165,38 @@ void board_teardown(void)
|
||||
}
|
||||
|
||||
static uint32_t _systick_count = 0;
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
_systick_count++;
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
_systick_count++;
|
||||
led_tick();
|
||||
}
|
||||
|
||||
|
||||
void pwm_teardown(NRF_PWM_Type* pwm )
|
||||
{
|
||||
void pwm_teardown(NRF_PWM_Type* pwm) {
|
||||
pwm->TASKS_SEQSTART[0] = 0;
|
||||
pwm->ENABLE = 0;
|
||||
pwm->ENABLE = 0;
|
||||
|
||||
pwm->PSEL.OUT[0] = 0xFFFFFFFF;
|
||||
pwm->PSEL.OUT[1] = 0xFFFFFFFF;
|
||||
pwm->PSEL.OUT[2] = 0xFFFFFFFF;
|
||||
pwm->PSEL.OUT[3] = 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;
|
||||
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;
|
||||
}
|
||||
|
||||
static uint16_t led_duty_cycles[PWM0_CH_NUM] = { 0 };
|
||||
static uint16_t led_duty_cycles[PWM0_CH_NUM] = {0};
|
||||
|
||||
#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;
|
||||
void led_pwm_init(uint32_t led_index, uint32_t led_pin) {
|
||||
NRF_PWM_Type* pwm = NRF_PWM0;
|
||||
|
||||
pwm->ENABLE = 0;
|
||||
|
||||
@@ -213,15 +205,15 @@ void led_pwm_init(uint32_t led_index, uint32_t led_pin)
|
||||
|
||||
pwm->PSEL.OUT[led_index] = led_pin;
|
||||
|
||||
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->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_duty_cycles);
|
||||
pwm->SEQ[0].CNT = 4; // default mode is Individual --> count must be 4
|
||||
pwm->SEQ[0].REFRESH = 0;
|
||||
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->ENABLE = 1;
|
||||
@@ -230,13 +222,11 @@ void led_pwm_init(uint32_t led_index, uint32_t led_pin)
|
||||
// pwm->TASKS_SEQSTART[0] = 1;
|
||||
}
|
||||
|
||||
void led_pwm_teardown(void)
|
||||
{
|
||||
void led_pwm_teardown(void) {
|
||||
pwm_teardown(NRF_PWM0);
|
||||
}
|
||||
|
||||
void led_pwm_duty_cycle(uint32_t led_index, uint16_t duty_cycle)
|
||||
{
|
||||
void led_pwm_duty_cycle(uint32_t led_index, uint16_t duty_cycle) {
|
||||
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);
|
||||
@@ -246,102 +236,103 @@ static uint32_t primary_cycle_length;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
static uint32_t secondary_cycle_length;
|
||||
#endif
|
||||
|
||||
void led_tick() {
|
||||
uint32_t millis = _systick_count;
|
||||
uint32_t millis = _systick_count;
|
||||
|
||||
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);
|
||||
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
|
||||
#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;
|
||||
static bool temp_color_active = false;
|
||||
void led_state(uint32_t state)
|
||||
{
|
||||
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 = 3000;
|
||||
break;
|
||||
|
||||
case STATE_BOOTLOADER_STARTED:
|
||||
case STATE_USB_UNMOUNTED:
|
||||
new_rgb_color = 0xff0000;
|
||||
primary_cycle_length = 300;
|
||||
break;
|
||||
void led_state(uint32_t state) {
|
||||
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 = 3000;
|
||||
break;
|
||||
|
||||
case STATE_WRITING_STARTED:
|
||||
temp_color = 0xff0000;
|
||||
primary_cycle_length = 100;
|
||||
break;
|
||||
case STATE_BOOTLOADER_STARTED:
|
||||
case STATE_USB_UNMOUNTED:
|
||||
new_rgb_color = 0xff0000;
|
||||
primary_cycle_length = 300;
|
||||
break;
|
||||
|
||||
case STATE_WRITING_FINISHED:
|
||||
// Empty means to unset any temp colors.
|
||||
primary_cycle_length = 3000;
|
||||
break;
|
||||
case STATE_WRITING_STARTED:
|
||||
temp_color = 0xff0000;
|
||||
primary_cycle_length = 100;
|
||||
break;
|
||||
|
||||
case STATE_BLE_CONNECTED:
|
||||
new_rgb_color = 0x0000ff;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
secondary_cycle_length = 3000;
|
||||
#else
|
||||
primary_cycle_length = 3000;
|
||||
#endif
|
||||
break;
|
||||
case STATE_WRITING_FINISHED:
|
||||
// Empty means to unset any temp colors.
|
||||
primary_cycle_length = 3000;
|
||||
break;
|
||||
|
||||
case STATE_BLE_DISCONNECTED:
|
||||
new_rgb_color = 0xff00ff;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
secondary_cycle_length = 300;
|
||||
#else
|
||||
primary_cycle_length = 300;
|
||||
#endif
|
||||
break;
|
||||
case STATE_BLE_CONNECTED:
|
||||
new_rgb_color = 0x0000ff;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
secondary_cycle_length = 3000;
|
||||
#else
|
||||
primary_cycle_length = 3000;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint8_t* final_color = NULL;
|
||||
new_rgb_color &= BOARD_RGB_BRIGHTNESS;
|
||||
if (temp_color != 0){
|
||||
temp_color &= BOARD_RGB_BRIGHTNESS;
|
||||
final_color = (uint8_t*)&temp_color;
|
||||
temp_color_active = true;
|
||||
} else if (new_rgb_color != rgb_color) {
|
||||
final_color = (uint8_t*)&new_rgb_color;
|
||||
rgb_color = new_rgb_color;
|
||||
} else if (temp_color_active) {
|
||||
final_color = (uint8_t*)&rgb_color;
|
||||
}
|
||||
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;
|
||||
}
|
||||
uint8_t* final_color = NULL;
|
||||
new_rgb_color &= BOARD_RGB_BRIGHTNESS;
|
||||
if (temp_color != 0) {
|
||||
temp_color &= BOARD_RGB_BRIGHTNESS;
|
||||
final_color = (uint8_t*) &temp_color;
|
||||
temp_color_active = true;
|
||||
} else if (new_rgb_color != rgb_color) {
|
||||
final_color = (uint8_t*) &new_rgb_color;
|
||||
rgb_color = new_rgb_color;
|
||||
} else if (temp_color_active) {
|
||||
final_color = (uint8_t*) &rgb_color;
|
||||
}
|
||||
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
|
||||
if (final_color != NULL) {
|
||||
neopixel_write(final_color);
|
||||
}
|
||||
if (final_color != NULL) {
|
||||
neopixel_write(final_color);
|
||||
}
|
||||
#else
|
||||
(void) final_color;
|
||||
(void) final_color;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -354,11 +345,10 @@ void led_state(uint32_t state)
|
||||
|
||||
#define BYTE_PER_PIXEL 3
|
||||
|
||||
static uint16_t pixels_pattern[NEOPIXELS_NUMBER*BYTE_PER_PIXEL * 8 + 2];
|
||||
static uint16_t pixels_pattern[NEOPIXELS_NUMBER * BYTE_PER_PIXEL * 8 + 2];
|
||||
|
||||
// use PWM1 for neopixel
|
||||
void neopixel_init(void)
|
||||
{
|
||||
void neopixel_init(void) {
|
||||
// To support both the SoftDevice + Neopixels we use the EasyDMA
|
||||
// feature from the NRF25. However this technique implies to
|
||||
// generate a pattern and store it on the memory. The actual
|
||||
@@ -394,40 +384,33 @@ void neopixel_init(void)
|
||||
// pwm->INTEN |= (PWM_INTEN_SEQEND0_Enabled<<PWM_INTEN_SEQEND0_Pos);
|
||||
|
||||
// PSEL must be configured before enabling PWM
|
||||
nrf_pwm_pins_set(pwm, (uint32_t[] ) { LED_NEOPIXEL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL });
|
||||
nrf_pwm_pins_set(pwm, (uint32_t[]) {LED_NEOPIXEL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL});
|
||||
|
||||
// Enable the PWM
|
||||
nrf_pwm_enable(pwm);
|
||||
}
|
||||
|
||||
void neopixel_teardown(void)
|
||||
{
|
||||
uint8_t rgb[3] = { 0, 0, 0 };
|
||||
void neopixel_teardown(void) {
|
||||
uint8_t rgb[3] = {0, 0, 0};
|
||||
|
||||
NRFX_DELAY_US(50); // wait for previous write is complete
|
||||
|
||||
neopixel_write(rgb);
|
||||
NRFX_DELAY_US(50); // wait for this write
|
||||
|
||||
pwm_teardown(NRF_PWM1);
|
||||
}
|
||||
|
||||
// write 3 bytes color RGB to built-in neopixel
|
||||
void neopixel_write (uint8_t *pixels)
|
||||
{
|
||||
void neopixel_write(uint8_t* pixels) {
|
||||
// convert RGB to GRB
|
||||
uint8_t grb[BYTE_PER_PIXEL] = {pixels[1], pixels[2], pixels[0]};
|
||||
uint16_t pos = 0; // bit position
|
||||
|
||||
// Set all neopixel to same value
|
||||
for (uint16_t n = 0; n < NEOPIXELS_NUMBER; n++ )
|
||||
{
|
||||
for(uint8_t c = 0; c < BYTE_PER_PIXEL; c++)
|
||||
{
|
||||
for (uint16_t n = 0; n < NEOPIXELS_NUMBER; n++) {
|
||||
for (uint8_t c = 0; c < BYTE_PER_PIXEL; c++) {
|
||||
uint8_t const pix = grb[c];
|
||||
|
||||
for ( uint8_t mask = 0x80; mask > 0; mask >>= 1 )
|
||||
{
|
||||
for (uint8_t mask = 0x80; mask > 0; mask >>= 1) {
|
||||
pixels_pattern[pos] = (pix & mask) ? MAGIC_T1H : MAGIC_T0H;
|
||||
pos++;
|
||||
}
|
||||
@@ -441,14 +424,15 @@ void neopixel_write (uint8_t *pixels)
|
||||
NRF_PWM_Type* pwm = NRF_PWM1;
|
||||
|
||||
nrf_pwm_seq_ptr_set(pwm, 0, pixels_pattern);
|
||||
nrf_pwm_seq_cnt_set(pwm, 0, sizeof(pixels_pattern)/2);
|
||||
nrf_pwm_seq_cnt_set(pwm, 0, sizeof(pixels_pattern) / 2);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
|
||||
nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0);
|
||||
|
||||
// blocking wait for sequence complete
|
||||
while( !nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0) ) {}
|
||||
while (!nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0)) {}
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LED_APA102
|
||||
@@ -460,8 +444,7 @@ void neopixel_write (uint8_t *pixels)
|
||||
static uint8_t pixels_pattern[PATTERN_SIZE() + 4];
|
||||
|
||||
// use SPIM1 for dotstar
|
||||
void neopixel_init(void)
|
||||
{
|
||||
void neopixel_init(void) {
|
||||
NRF_SPIM_Type* spi = NRF_SPIM1;
|
||||
|
||||
nrf_spim_disable(spi);
|
||||
@@ -492,8 +475,7 @@ void neopixel_init(void)
|
||||
neopixel_write(rgb);
|
||||
}
|
||||
|
||||
void neopixel_teardown(void)
|
||||
{
|
||||
void neopixel_teardown(void) {
|
||||
uint8_t rgb[3] = {0, 0, 0 };
|
||||
neopixel_write(rgb);
|
||||
|
||||
@@ -502,8 +484,7 @@ void neopixel_teardown(void)
|
||||
}
|
||||
|
||||
// write 3 bytes color RGB to built-in neopixel
|
||||
void neopixel_write (uint8_t *pixels)
|
||||
{
|
||||
void neopixel_write (uint8_t *pixels) {
|
||||
NRF_SPIM_Type* spi = NRF_SPIM1;
|
||||
|
||||
//brightness, blue, green, red
|
||||
@@ -514,10 +495,10 @@ void neopixel_write (uint8_t *pixels)
|
||||
pixels_pattern[3] = 0;
|
||||
|
||||
for (uint8_t i = 4; i < PATTERN_SIZE(); i+=4) {
|
||||
pixels_pattern[i] = bbgr[0];
|
||||
pixels_pattern[i+1] = bbgr[1];
|
||||
pixels_pattern[i+2] = bbgr[2];
|
||||
pixels_pattern[i+3] = bbgr[3];
|
||||
pixels_pattern[i] = bbgr[0];
|
||||
pixels_pattern[i+1] = bbgr[1];
|
||||
pixels_pattern[i+2] = bbgr[2];
|
||||
pixels_pattern[i+3] = bbgr[3];
|
||||
}
|
||||
|
||||
pixels_pattern[PATTERN_SIZE()] = 0xff;
|
||||
@@ -545,15 +526,13 @@ void neopixel_write (uint8_t *pixels)
|
||||
#define LED_RGB_BLUE 2
|
||||
#define LED_RGB_GREEN 3
|
||||
|
||||
void neopixel_init(void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
void neopixel_teardown(void) {
|
||||
uint8_t rgb[3] = { 0, 0, 0 };
|
||||
neopixel_write(rgb);
|
||||
nrf_gpio_cfg_default(LED_RGB_RED_PIN);
|
||||
@@ -562,8 +541,7 @@ void neopixel_teardown(void)
|
||||
}
|
||||
|
||||
// write 3 bytes color to a built-in neopixel
|
||||
void neopixel_write (uint8_t *pixels)
|
||||
{
|
||||
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]);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Ha Thach for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _FEATHER_NRF52840_SENSE_TFT_H
|
||||
#define _FEATHER_NRF52840_SENSE_TFT_H
|
||||
|
||||
#define _PINNUM(port, pin) ((port)*32 + (pin))
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* LED
|
||||
*------------------------------------------------------------------*/
|
||||
#define LEDS_NUMBER 1
|
||||
#define LED_PRIMARY_PIN _PINNUM(0, 11)
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
#define LED_NEOPIXEL _PINNUM(1, 8)
|
||||
#define NEOPIXEL_POWER_PIN _PINNUM(1, 2)
|
||||
#define NEOPIXELS_NUMBER 1
|
||||
#define BOARD_RGB_BRIGHTNESS 0x040404
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* BUTTON
|
||||
*------------------------------------------------------------------*/
|
||||
#define BUTTONS_NUMBER 2
|
||||
#define BUTTON_1 _PINNUM(1, 6)
|
||||
#define BUTTON_2 _PINNUM(1, 10) // DFU pin
|
||||
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLE OTA
|
||||
//--------------------------------------------------------------------+
|
||||
#define BLEDIS_MANUFACTURER "Adafruit Industries"
|
||||
#define BLEDIS_MODEL "Feather nRF52840 Sense TFT"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0087
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0088
|
||||
|
||||
//------------- UF2 -------------//
|
||||
#define UF2_PRODUCT_NAME "Adafruit Feather nRF52840 Sense TFT"
|
||||
#define UF2_VOLUME_LABEL "FTHRSNSBOOT"
|
||||
#define UF2_BOARD_ID "nRF52840-FeatherSenseTFT-revA"
|
||||
#define UF2_INDEX_URL "https://www.adafruit.com/product/"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
MCU_SUB_VARIANT = nrf52840
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "boards.h"
|
||||
#include "uf2/configkeys.h"
|
||||
|
||||
__attribute__((used, section(".bootloaderConfig")))
|
||||
const uint32_t bootloaderConfig[] =
|
||||
{
|
||||
/* CF2 START */
|
||||
CFG_MAGIC0, CFG_MAGIC1, // magic
|
||||
5, 100, // used entries, total entries
|
||||
|
||||
204, 0x100000, // FLASH_BYTES = 0x100000
|
||||
205, 0x40000, // RAM_BYTES = 0x40000
|
||||
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
|
||||
209, 0xada52840, // UF2_FAMILY = 0xada52840
|
||||
210, 0x20, // PINS_PORT_SIZE = PA_32
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
/* CF2 END */
|
||||
};
|
||||
+61
-110
@@ -68,6 +68,7 @@
|
||||
#include "nrfx_nvmc.h"
|
||||
|
||||
#ifdef NRF_USBD
|
||||
|
||||
#include "uf2/uf2.h"
|
||||
#include "nrf_usbd.h"
|
||||
#include "tusb.h"
|
||||
@@ -80,16 +81,11 @@ void usb_teardown(void);
|
||||
extern void tusb_hal_nrf_power_event(uint32_t event);
|
||||
|
||||
#else
|
||||
|
||||
#define usb_init(x) led_state(STATE_USB_MOUNTED) // mark nrf52832 as mounted
|
||||
#define usb_teardown()
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
/*
|
||||
* Blinking patterns:
|
||||
* - DFU Serial : LED Status blink
|
||||
@@ -132,20 +128,21 @@ extern void tusb_hal_nrf_power_event(uint32_t event);
|
||||
// These value must be the same with one in dfu_transport_ble.c
|
||||
#define BLEGAP_EVENT_LENGTH 6
|
||||
#define BLEGATT_ATT_MTU_MAX 23
|
||||
enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
|
||||
enum {
|
||||
BLE_CONN_CFG_HIGH_BANDWIDTH = 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
uint32_t* dbl_reset_mem = ((uint32_t*) DFU_DBL_RESET_MEM );
|
||||
uint32_t* dbl_reset_mem = ((uint32_t*) DFU_DBL_RESET_MEM);
|
||||
|
||||
// true if ble, false if serial
|
||||
bool _ota_dfu = false;
|
||||
bool _ota_connected = false;
|
||||
bool _sd_inited = false;
|
||||
|
||||
bool is_ota(void)
|
||||
{
|
||||
bool is_ota(void) {
|
||||
return _ota_dfu;
|
||||
}
|
||||
|
||||
@@ -154,18 +151,16 @@ static uint32_t ble_stack_init(void);
|
||||
|
||||
// The SoftDevice must only be initialized if a chip reset has occurred.
|
||||
// Soft reset (jump ) from application must not reinitialize the SoftDevice.
|
||||
static void mbr_init_sd(void)
|
||||
{
|
||||
static void mbr_init_sd(void) {
|
||||
PRINTF("SD_MBR_COMMAND_INIT_SD\r\n");
|
||||
sd_mbr_command_t com = { .command = SD_MBR_COMMAND_INIT_SD };
|
||||
sd_mbr_command_t com = {.command = SD_MBR_COMMAND_INIT_SD};
|
||||
sd_mbr_command(&com);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
// Populate Boot Address and MBR Param into MBR if not already
|
||||
// MBR_BOOTLOADER_ADDR/MBR_PARAM_PAGE_ADDR are used if available, else UICR registers are used
|
||||
// Note: skip it for now since this will prevent us to change the size of bootloader in the future
|
||||
@@ -177,14 +172,11 @@ int main(void)
|
||||
|
||||
board_init();
|
||||
bootloader_init();
|
||||
|
||||
PRINTF("Bootloader Start\r\n");
|
||||
|
||||
led_state(STATE_BOOTLOADER_STARTED);
|
||||
|
||||
// When updating SoftDevice, bootloader will reset before swapping SD
|
||||
if (bootloader_dfu_sd_in_progress())
|
||||
{
|
||||
if (bootloader_dfu_sd_in_progress()) {
|
||||
led_state(STATE_WRITING_STARTED);
|
||||
|
||||
bootloader_dfu_sd_update_continue();
|
||||
@@ -207,14 +199,11 @@ int main(void)
|
||||
* - sd_softdevice_vector_table_base_set(APP_ADDR)
|
||||
* - jump to App reset
|
||||
*/
|
||||
|
||||
if (bootloader_app_is_valid() && !bootloader_dfu_sd_in_progress())
|
||||
{
|
||||
if (bootloader_app_is_valid() && !bootloader_dfu_sd_in_progress()) {
|
||||
PRINTF("App is valid\r\n");
|
||||
if ( is_sd_existed() )
|
||||
{
|
||||
if (is_sd_existed()) {
|
||||
// MBR forward IRQ to SD (if not already)
|
||||
if ( !_sd_inited ) mbr_init_sd();
|
||||
if (!_sd_inited) mbr_init_sd();
|
||||
|
||||
// Make sure SD is disabled
|
||||
sd_softdevice_disable();
|
||||
@@ -230,8 +219,7 @@ int main(void)
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
static void check_dfu_mode(void)
|
||||
{
|
||||
static void check_dfu_mode(void) {
|
||||
uint32_t const gpregret = NRF_POWER->GPREGRET;
|
||||
|
||||
// SD is already Initialized in case of BOOTLOADER_DFU_OTA_MAGIC
|
||||
@@ -249,7 +237,7 @@ static void check_dfu_mode(void)
|
||||
|
||||
// start either serial, uf2 or ble
|
||||
bool dfu_start = _ota_dfu || serial_only_dfu || uf2_dfu ||
|
||||
(((*dbl_reset_mem) == DFU_DBL_RESET_MAGIC) && reason_reset_pin);
|
||||
(((*dbl_reset_mem) == DFU_DBL_RESET_MAGIC) && reason_reset_pin);
|
||||
|
||||
// Clear GPREGRET if it is our values
|
||||
if (dfu_start || dfu_skip) NRF_POWER->GPREGRET = 0;
|
||||
@@ -262,7 +250,7 @@ static void check_dfu_mode(void)
|
||||
dfu_start = dfu_start || button_pressed(BUTTON_DFU);
|
||||
|
||||
// DFU + FRESET are pressed --> OTA
|
||||
_ota_dfu = _ota_dfu || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ;
|
||||
_ota_dfu = _ota_dfu || (button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET));
|
||||
|
||||
bool const valid_app = bootloader_app_is_valid();
|
||||
bool const just_start_app = valid_app && !dfu_start && (*dbl_reset_mem) == DFU_DBL_RESET_APP;
|
||||
@@ -270,8 +258,7 @@ static void check_dfu_mode(void)
|
||||
if (!just_start_app && APP_ASKS_FOR_SINGLE_TAP_RESET()) dfu_start = 1;
|
||||
|
||||
// App mode: Double Reset detection or DFU startup for nrf52832
|
||||
if ( ! (just_start_app || dfu_start || !valid_app) )
|
||||
{
|
||||
if (!(just_start_app || dfu_start || !valid_app)) {
|
||||
#ifdef NRF52832_XXAA
|
||||
/* Even DFU is not active, we still force an 1000 ms dfu serial mode when startup
|
||||
* to support auto programming from Arduino IDE
|
||||
@@ -281,8 +268,7 @@ static void check_dfu_mode(void)
|
||||
bootloader_dfu_start(false, DFU_SERIAL_STARTUP_INTERVAL, false);
|
||||
#else
|
||||
// Note: RESETREAS is not clear by bootloader, it should be cleared by application upon init()
|
||||
if (reason_reset_pin)
|
||||
{
|
||||
if (reason_reset_pin) {
|
||||
// Register our first reset for double reset detection
|
||||
(*dbl_reset_mem) = DFU_DBL_RESET_MAGIC;
|
||||
|
||||
@@ -292,77 +278,59 @@ static void check_dfu_mode(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (APP_ASKS_FOR_SINGLE_TAP_RESET())
|
||||
{
|
||||
if (APP_ASKS_FOR_SINGLE_TAP_RESET()) {
|
||||
(*dbl_reset_mem) = DFU_DBL_RESET_APP;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
(*dbl_reset_mem) = 0;
|
||||
}
|
||||
|
||||
// Enter DFU mode accordingly to input
|
||||
if ( dfu_start || !valid_app )
|
||||
{
|
||||
if ( _ota_dfu )
|
||||
{
|
||||
if (dfu_start || !valid_app) {
|
||||
if (_ota_dfu) {
|
||||
led_state(STATE_BLE_DISCONNECTED);
|
||||
|
||||
if (!_sd_inited ) mbr_init_sd();
|
||||
if (!_sd_inited) mbr_init_sd();
|
||||
_sd_inited = true;
|
||||
|
||||
ble_stack_init();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
led_state(STATE_USB_UNMOUNTED);
|
||||
usb_init(serial_only_dfu);
|
||||
}
|
||||
|
||||
// Initiate an update of the firmware.
|
||||
if (APP_ASKS_FOR_SINGLE_TAP_RESET() || uf2_dfu || serial_only_dfu)
|
||||
{
|
||||
if (APP_ASKS_FOR_SINGLE_TAP_RESET() || uf2_dfu || serial_only_dfu) {
|
||||
// If USB is not enumerated in 3s (eg. because we're running on battery), we restart into app.
|
||||
bootloader_dfu_start(_ota_dfu, 3000, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
bootloader_dfu_start(_ota_dfu, 3000, true);
|
||||
} else {
|
||||
// No timeout if bootloader requires user action (double-reset).
|
||||
bootloader_dfu_start(_ota_dfu, 0, false);
|
||||
bootloader_dfu_start(_ota_dfu, 0, false);
|
||||
}
|
||||
|
||||
if ( _ota_dfu )
|
||||
{
|
||||
if (_ota_dfu) {
|
||||
sd_softdevice_disable();
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
usb_teardown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initializes the SotdDevice by following SD specs section
|
||||
// "Master Boot Record and SoftDevice initializaton procedure"
|
||||
static uint32_t ble_stack_init(void)
|
||||
{
|
||||
static uint32_t ble_stack_init(void) {
|
||||
// Forward vector table to bootloader address so that we can handle BLE events
|
||||
sd_softdevice_vector_table_base_set(BOOTLOADER_REGION_START);
|
||||
|
||||
// Enable Softdevice, Use Internal OSC to compatible with all boards
|
||||
nrf_clock_lf_cfg_t clock_cfg =
|
||||
{
|
||||
nrf_clock_lf_cfg_t clock_cfg = {
|
||||
.source = NRF_CLOCK_LF_SRC_RC,
|
||||
.rc_ctiv = 16,
|
||||
.rc_temp_ctiv = 2,
|
||||
.accuracy = NRF_CLOCK_LF_ACCURACY_250_PPM
|
||||
};
|
||||
|
||||
sd_softdevice_enable(&clock_cfg, app_error_fault_handler);
|
||||
sd_nvic_EnableIRQ(SD_EVT_IRQn);
|
||||
|
||||
/*------------- Configure BLE params -------------*/
|
||||
extern uint32_t __data_start__[]; // defined in linker
|
||||
extern uint32_t __data_start__[]; // defined in linker
|
||||
uint32_t ram_start = (uint32_t) __data_start__;
|
||||
|
||||
ble_cfg_t blecfg;
|
||||
@@ -370,9 +338,9 @@ static uint32_t ble_stack_init(void)
|
||||
// Configure the maximum number of connections.
|
||||
varclr(&blecfg);
|
||||
blecfg.gap_cfg.role_count_cfg.adv_set_count = 1;
|
||||
blecfg.gap_cfg.role_count_cfg.periph_role_count = 1;
|
||||
blecfg.gap_cfg.role_count_cfg.periph_role_count = 1;
|
||||
blecfg.gap_cfg.role_count_cfg.central_role_count = 0;
|
||||
blecfg.gap_cfg.role_count_cfg.central_sec_count = 0;
|
||||
blecfg.gap_cfg.role_count_cfg.central_sec_count = 0;
|
||||
sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &blecfg, ram_start);
|
||||
|
||||
// NRF_DFU_BLE_REQUIRES_BONDS
|
||||
@@ -389,7 +357,7 @@ static uint32_t ble_stack_init(void)
|
||||
// Event Length + HVN queue + WRITE CMD queue setting affecting bandwidth
|
||||
varclr(&blecfg);
|
||||
blecfg.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_HIGH_BANDWIDTH;
|
||||
blecfg.conn_cfg.params.gap_conn_cfg.conn_count = 1;
|
||||
blecfg.conn_cfg.params.gap_conn_cfg.conn_count = 1;
|
||||
blecfg.conn_cfg.params.gap_conn_cfg.event_length = BLEGAP_EVENT_LENGTH;
|
||||
sd_ble_cfg_set(BLE_CONN_CFG_GAP, &blecfg, ram_start);
|
||||
|
||||
@@ -407,19 +375,16 @@ static uint32_t ble_stack_init(void)
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Error Handler
|
||||
//--------------------------------------------------------------------+
|
||||
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
|
||||
{
|
||||
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */
|
||||
if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */
|
||||
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) {
|
||||
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */
|
||||
if ((*ARM_CM_DHCSR) & 1UL) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void assert_nrf_callback (uint16_t line_num, uint8_t const * p_file_name)
|
||||
{
|
||||
void assert_nrf_callback(uint16_t line_num, uint8_t const* p_file_name) {
|
||||
app_error_fault_handler(0xDEADBEEF, 0, 0);
|
||||
}
|
||||
|
||||
@@ -428,9 +393,8 @@ void assert_nrf_callback (uint16_t line_num, uint8_t const * p_file_name)
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
// Process BLE event from SD
|
||||
uint32_t proc_ble(void)
|
||||
{
|
||||
__ALIGN(4) uint8_t ev_buf[ BLE_EVT_LEN_MAX(BLEGATT_ATT_MTU_MAX) ];
|
||||
uint32_t proc_ble(void) {
|
||||
__ALIGN(4) uint8_t ev_buf[BLE_EVT_LEN_MAX(BLEGATT_ATT_MTU_MAX)];
|
||||
uint16_t ev_len = BLE_EVT_LEN_MAX(BLEGATT_ATT_MTU_MAX);
|
||||
|
||||
// Init header
|
||||
@@ -441,25 +405,24 @@ uint32_t proc_ble(void)
|
||||
uint32_t err = sd_ble_evt_get(ev_buf, &ev_len);
|
||||
|
||||
// Handle valid event, ignore error
|
||||
if( NRF_SUCCESS == err)
|
||||
{
|
||||
switch (evt->header.evt_id)
|
||||
{
|
||||
if (NRF_SUCCESS == err) {
|
||||
switch (evt->header.evt_id) {
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
_ota_connected = true;
|
||||
led_state(STATE_BLE_CONNECTED);
|
||||
break;
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
_ota_connected = false;
|
||||
led_state(STATE_BLE_DISCONNECTED);
|
||||
break;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// from dfu_transport_ble
|
||||
extern void ble_evt_dispatch(ble_evt_t * p_ble_evt);
|
||||
extern void ble_evt_dispatch(ble_evt_t* p_ble_evt);
|
||||
ble_evt_dispatch(evt);
|
||||
}
|
||||
|
||||
@@ -467,68 +430,56 @@ uint32_t proc_ble(void)
|
||||
}
|
||||
|
||||
// process SOC event from SD
|
||||
uint32_t proc_soc(void)
|
||||
{
|
||||
uint32_t proc_soc(void) {
|
||||
uint32_t soc_evt = 0;
|
||||
uint32_t err = sd_evt_get(&soc_evt);
|
||||
|
||||
if (NRF_SUCCESS == err)
|
||||
{
|
||||
if (NRF_SUCCESS == err) {
|
||||
pstorage_sys_event_handler(soc_evt);
|
||||
|
||||
#ifdef NRF_USBD
|
||||
/*------------- usb power event handler -------------*/
|
||||
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
|
||||
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
|
||||
(soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
|
||||
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED) ? NRFX_POWER_USB_EVT_DETECTED :
|
||||
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
|
||||
(soc_evt == NRF_EVT_POWER_USB_REMOVED) ? NRFX_POWER_USB_EVT_REMOVED : -1;
|
||||
|
||||
if ( usbevt >= 0) tusb_hal_nrf_power_event((uint32_t) usbevt);
|
||||
if (usbevt >= 0) tusb_hal_nrf_power_event((uint32_t) usbevt);
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void proc_sd_task(void* evt_data, uint16_t evt_size)
|
||||
{
|
||||
void proc_sd_task(void* evt_data, uint16_t evt_size) {
|
||||
(void) evt_data;
|
||||
(void) evt_size;
|
||||
|
||||
// process BLE and SOC until there is no more events
|
||||
while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) )
|
||||
{
|
||||
|
||||
while ((NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc())) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
void SD_EVT_IRQHandler(void)
|
||||
{
|
||||
void SD_EVT_IRQHandler(void) {
|
||||
// Use App Scheduler to defer handling code in non-isr context
|
||||
app_sched_event_put(NULL, 0, proc_sd_task);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// RTT printf retarget for Debug
|
||||
//--------------------------------------------------------------------+
|
||||
#ifdef CFG_DEBUG
|
||||
|
||||
#include "SEGGER_RTT.h"
|
||||
|
||||
__attribute__ ((used))
|
||||
int _write (int fhdl, const void *buf, size_t count)
|
||||
{
|
||||
__attribute__ ((used)) int _write (int fhdl, const void *buf, size_t count) {
|
||||
(void) fhdl;
|
||||
SEGGER_RTT_Write(0, (char*) buf, (int) count);
|
||||
return count;
|
||||
}
|
||||
|
||||
__attribute__ ((used))
|
||||
int _read (int fhdl, char *buf, size_t count)
|
||||
{
|
||||
__attribute__ ((used)) int _read (int fhdl, char *buf, size_t count) {
|
||||
(void) fhdl;
|
||||
return SEGGER_RTT_Read(0, buf, count);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user