Skip to content

Commit 91f16ad

Browse files
committed
add support for APA102 LEDs
1 parent 81da515 commit 91f16ad

File tree

1 file changed

+93
-4
lines changed

1 file changed

+93
-4
lines changed

src/boards/boards.c

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
#include "boards.h"
2626
#include "nrf_pwm.h"
27+
#include "nrf_spim.h"
28+
#include "nrf_clock.h"
2729
#include "app_scheduler.h"
2830
#include "app_timer.h"
2931

@@ -33,7 +35,7 @@
3335
#define SCHED_MAX_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Maximum size of scheduler events. */
3436
#define SCHED_QUEUE_SIZE 30 /**< Maximum number of events in the scheduler queue. */
3537

36-
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
38+
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
3739
void neopixel_init(void);
3840
void neopixel_write(uint8_t *pixels);
3941
void neopixel_teardown(void);
@@ -71,14 +73,15 @@ void board_init(void)
7173
button_init(BUTTON_FRESET);
7274
NRFX_DELAY_US(100); // wait for the pin state is stable
7375

76+
#if LEDS_NUMBER > 0
7477
// use PMW0 for LED RED
7578
led_pwm_init(LED_PRIMARY, LED_PRIMARY_PIN);
7679
#if LEDS_NUMBER > 1
7780
led_pwm_init(LED_SECONDARY, LED_SECONDARY_PIN);
7881
#endif
79-
82+
#endif
8083
// use neopixel for use enumeration
81-
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
84+
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
8285
neopixel_init();
8386
#endif
8487

@@ -126,7 +129,9 @@ void board_teardown(void)
126129
SysTick->CTRL = 0;
127130

128131
// Disable and reset PWM for LEDs
132+
#if LEDS_NUMBER > 0
129133
led_pwm_teardown();
134+
#endif
130135

131136
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
132137
neopixel_teardown();
@@ -317,7 +322,7 @@ void led_state(uint32_t state)
317322
} else if (temp_color_active) {
318323
final_color = (uint8_t*)&rgb_color;
319324
}
320-
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
325+
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
321326
if (final_color != NULL) {
322327
neopixel_write(final_color);
323328
}
@@ -432,6 +437,90 @@ void neopixel_write (uint8_t *pixels)
432437
}
433438
#endif
434439

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

437526
#ifdef LED_SECONDARY_PIN

0 commit comments

Comments
 (0)