Created
September 16, 2018 23:17
-
-
Save monkbroc/e204b870e776460ac45148fc1dda83d7 to your computer and use it in GitHub Desktop.
Hardware accelerated Neopixel for nRF52840
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "application.h" | |
#include "nrfx_pwm.h" | |
#include "nrf_gpio.h" | |
#include "pinmap_impl.h" | |
SYSTEM_MODE(MANUAL); | |
#define PIXEL_COUNT 44 | |
#define BITS_PER_PIXEL 24 | |
#define pin D4 | |
// D4 { NRF_PORT_1, 8, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 1, 0, EXTI_CHANNEL_NONE}, | |
#define NRFX_PWM_DUTY_INVERTED 0x8000 | |
#define BIT0 (NRFX_PWM_DUTY_INVERTED | 5) | |
#define BIT1 (NRFX_PWM_DUTY_INVERTED | 14) | |
uint16_t seq_values[BITS_PER_PIXEL * PIXEL_COUNT] = { BIT0 }; | |
uint8_t nrf_pins[NRF_PWM_CHANNEL_COUNT] = { | |
NRFX_PWM_PIN_NOT_USED, | |
NRFX_PWM_PIN_NOT_USED, | |
NRFX_PWM_PIN_NOT_USED, | |
NRFX_PWM_PIN_NOT_USED, | |
}; | |
const nrfx_pwm_t pwms[] = { | |
NRFX_PWM_INSTANCE(0), | |
NRFX_PWM_INSTANCE(1), | |
NRFX_PWM_INSTANCE(2), | |
NRFX_PWM_INSTANCE(3) | |
}; | |
void sequenceHandler(nrfx_pwm_evt_type_t event_type); | |
uint32_t Color(uint8_t r, uint8_t g, uint8_t b); | |
uint32_t Wheel(uint8_t WheelPos); | |
void show(); | |
void rainbow(); | |
void setPixelColor(uint8_t i, uint32_t color); | |
void setup() { | |
ret_code_t ret_code; | |
NRF5x_Pin_Info* PIN_MAP = HAL_Pin_Map(); | |
uint8_t pwm_num = PIN_MAP[pin].pwm_instance; | |
uint8_t pwm_channel = PIN_MAP[pin].pwm_channel; | |
nrf_pwm_clk_t pwm_clock = NRF_PWM_CLK_16MHz; | |
uint16_t period_hwu = 20; // 800 kHz with 16 MHz clock | |
nrf_pins[pwm_channel] = NRF_GPIO_PIN_MAP(PIN_MAP[pin].gpio_port, PIN_MAP[pin].gpio_pin); | |
nrfx_pwm_config_t const config = { | |
.output_pins = | |
{ | |
nrf_pins[0], // channel 0 | |
nrf_pins[1], // channel 1 | |
nrf_pins[2], // channel 2 | |
nrf_pins[3], // channel 3 | |
}, | |
.irq_priority = APP_IRQ_PRIORITY_LOWEST, | |
.base_clock = pwm_clock, | |
.count_mode = NRF_PWM_MODE_UP, | |
.top_value = period_hwu, | |
.load_mode = NRF_PWM_LOAD_COMMON, | |
.step_mode = NRF_PWM_STEP_AUTO | |
}; | |
ret_code = nrfx_pwm_init(&pwms[pwm_num], &config, sequenceHandler); | |
if (ret_code) | |
{ | |
return; | |
} | |
HAL_Set_Pin_Function(pin, PF_PWM); | |
} | |
bool started = false; | |
uint32_t stopTime = 0; | |
void loop() { | |
if (started || millis() - stopTime < 20) { | |
return; | |
} | |
rainbow(); | |
} | |
void show() { | |
started = true; | |
ret_code_t ret_code; | |
NRF5x_Pin_Info* PIN_MAP = HAL_Pin_Map(); | |
uint8_t pwm_num = PIN_MAP[pin].pwm_instance; | |
nrf_pwm_sequence_t const seq = { | |
.values = { .p_common = seq_values }, | |
.length = NRF_PWM_VALUES_LENGTH(seq_values), | |
.repeats = 0, | |
.end_delay = 0 | |
}; | |
ret_code = nrfx_pwm_simple_playback(&pwms[pwm_num], &seq, 1, NRFX_PWM_FLAG_STOP); | |
if (ret_code) | |
{ | |
return; | |
} | |
} | |
void sequenceHandler(nrfx_pwm_evt_type_t event_type) { | |
if (event_type == NRFX_PWM_EVT_STOPPED) { | |
started = false; | |
stopTime = millis(); | |
} | |
} | |
/* Fun! */ | |
void rainbow() { | |
static uint8_t j = 0; | |
for(uint8_t i = 0; i < PIXEL_COUNT; i++) { | |
setPixelColor(i, Wheel(4 * i + j)); | |
} | |
show(); | |
j++; | |
} | |
uint32_t Color(uint8_t r, uint8_t g, uint8_t b) { | |
return (g << 16) | (r << 8) | b; | |
} | |
uint32_t Wheel(uint8_t WheelPos) { | |
if(WheelPos < 85) { | |
return Color(WheelPos * 3, 255 - WheelPos * 3, 0); | |
} else if(WheelPos < 170) { | |
WheelPos -= 85; | |
return Color(255 - WheelPos * 3, 0, WheelPos * 3); | |
} else { | |
WheelPos -= 170; | |
return Color(0, WheelPos * 3, 255 - WheelPos * 3); | |
} | |
} | |
void setPixelColor(uint8_t i, uint32_t color) { | |
uint16_t* p = &seq_values[i * BITS_PER_PIXEL]; | |
uint32_t mask = 0x00800000; | |
while (mask) { | |
if (color & mask) { | |
*p = BIT1; | |
} else { | |
*p = BIT0; | |
} | |
mask >>= 1; | |
p++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment