Skip to content

Commit cb916d3

Browse files
authored
Merge pull request #192 from jamesadevine/apa102
add support for APA102 LEDs
2 parents 81da515 + 0670265 commit cb916d3

File tree

1 file changed

+96
-5
lines changed

1 file changed

+96
-5
lines changed

src/boards/boards.c

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,17 @@
2727
#include "app_scheduler.h"
2828
#include "app_timer.h"
2929

30+
#ifdef LED_APA102
31+
#include "nrf_spim.h"
32+
#endif
33+
3034
//--------------------------------------------------------------------+
3135
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
3236
//--------------------------------------------------------------------+
3337
#define SCHED_MAX_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Maximum size of scheduler events. */
3438
#define SCHED_QUEUE_SIZE 30 /**< Maximum number of events in the scheduler queue. */
3539

36-
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
40+
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
3741
void neopixel_init(void);
3842
void neopixel_write(uint8_t *pixels);
3943
void neopixel_teardown(void);
@@ -71,14 +75,15 @@ void board_init(void)
7175
button_init(BUTTON_FRESET);
7276
NRFX_DELAY_US(100); // wait for the pin state is stable
7377

78+
#if LEDS_NUMBER > 0
7479
// use PMW0 for LED RED
7580
led_pwm_init(LED_PRIMARY, LED_PRIMARY_PIN);
7681
#if LEDS_NUMBER > 1
7782
led_pwm_init(LED_SECONDARY, LED_SECONDARY_PIN);
7883
#endif
79-
84+
#endif
8085
// use neopixel for use enumeration
81-
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
86+
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
8287
neopixel_init();
8388
#endif
8489

@@ -126,9 +131,11 @@ void board_teardown(void)
126131
SysTick->CTRL = 0;
127132

128133
// Disable and reset PWM for LEDs
134+
#if LEDS_NUMBER > 0
129135
led_pwm_teardown();
136+
#endif
130137

131-
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
138+
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
132139
neopixel_teardown();
133140
#endif
134141

@@ -317,7 +324,7 @@ void led_state(uint32_t state)
317324
} else if (temp_color_active) {
318325
final_color = (uint8_t*)&rgb_color;
319326
}
320-
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
327+
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
321328
if (final_color != NULL) {
322329
neopixel_write(final_color);
323330
}
@@ -432,6 +439,90 @@ void neopixel_write (uint8_t *pixels)
432439
}
433440
#endif
434441

442+
#ifdef LED_APA102
443+
#define BYTE_PER_PIXEL 4
444+
445+
// 4 zero bytes are required to initiate update
446+
#define PATTERN_SIZE() ((APA102_NUMBER*BYTE_PER_PIXEL) + 4)
447+
// N/2 * 1 bits are required at the end
448+
static uint8_t pixels_pattern[PATTERN_SIZE() + 4];
449+
450+
// use SPIM1 for dotstar
451+
void neopixel_init(void)
452+
{
453+
NRF_SPIM_Type* spi = NRF_SPIM1;
454+
455+
nrf_spim_disable(spi);
456+
457+
nrf_gpio_pin_set(LED_APA102_CLK);
458+
459+
nrf_gpio_cfg(LED_APA102_CLK,
460+
NRF_GPIO_PIN_DIR_OUTPUT,
461+
NRF_GPIO_PIN_INPUT_CONNECT,
462+
NRF_GPIO_PIN_NOPULL,
463+
NRF_GPIO_PIN_S0S1,
464+
NRF_GPIO_PIN_NOSENSE);
465+
466+
nrf_gpio_pin_clear(LED_APA102_DATA);
467+
nrf_gpio_cfg_output(LED_APA102_DATA);
468+
469+
nrf_spim_pins_set(spi, LED_APA102_CLK, LED_APA102_DATA, 0xFFFFFFFF);
470+
nrf_spim_frequency_set(spi, NRF_SPIM_FREQ_4M);
471+
nrf_spim_configure(spi, NRF_SPIM_MODE_3, NRF_SPIM_BIT_ORDER_MSB_FIRST);
472+
473+
nrf_spim_orc_set(spi, 0);
474+
nrf_spim_tx_list_disable(spi);
475+
476+
// Enable the spi
477+
nrf_spim_enable(spi);
478+
479+
uint8_t rgb[3] = {0, 0, 0 };
480+
neopixel_write(rgb);
481+
}
482+
483+
void neopixel_teardown(void)
484+
{
485+
uint8_t rgb[3] = {0, 0, 0 };
486+
neopixel_write(rgb);
487+
488+
NRF_SPIM_Type* spi = NRF_SPIM1;
489+
nrf_spim_disable(spi);
490+
}
491+
492+
// write 3 bytes color RGB to built-in neopixel
493+
void neopixel_write (uint8_t *pixels)
494+
{
495+
NRF_SPIM_Type* spi = NRF_SPIM1;
496+
497+
//brightness, blue, green, red
498+
uint8_t bbgr[BYTE_PER_PIXEL] = {0xE0 | LED_APA102_BRIGHTNESS, pixels[0], pixels[1], pixels[2]};
499+
pixels_pattern[0] = 0;
500+
pixels_pattern[1] = 0;
501+
pixels_pattern[2] = 0;
502+
pixels_pattern[3] = 0;
503+
504+
for (uint8_t i = 4; i < PATTERN_SIZE(); i+=4) {
505+
pixels_pattern[i] = bbgr[0];
506+
pixels_pattern[i+1] = bbgr[1];
507+
pixels_pattern[i+2] = bbgr[2];
508+
pixels_pattern[i+3] = bbgr[3];
509+
}
510+
511+
pixels_pattern[PATTERN_SIZE()] = 0xff;
512+
pixels_pattern[PATTERN_SIZE()+1] = 0xff;
513+
pixels_pattern[PATTERN_SIZE()+2] = 0xff;
514+
pixels_pattern[PATTERN_SIZE()+3] = 0xff;
515+
516+
nrf_spim_tx_buffer_set(spi, pixels_pattern, PATTERN_SIZE() + 4);
517+
nrf_spim_event_clear(spi, NRF_SPIM_EVENT_ENDTX);
518+
519+
nrf_spim_task_trigger(spi, NRF_SPIM_TASK_START);
520+
521+
while(!nrf_spim_event_check(spi, NRF_SPIM_EVENT_ENDTX));
522+
}
523+
#endif
524+
525+
435526
#if defined(LED_RGB_RED_PIN) && defined(LED_RGB_GREEN_PIN) && defined(LED_RGB_BLUE_PIN)
436527

437528
#ifdef LED_SECONDARY_PIN

0 commit comments

Comments
 (0)