Simple neopixel (WS2812) library, tuned for stm32 (L432) at 80 MHz Should be compatible with any stm32, different clock speed may require timing adjustments in neopixel.c

Dependents:   NEOPIXEL_SAMPLE

Committer:
tichise
Date:
Thu Jan 02 07:56:44 2020 +0000
Revision:
1:415459e3f93b
Parent:
0:a81364d9a67b
Fixed __nop from lowercase to uppercase to work with PlatformIO

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MightyPork 0:a81364d9a67b 1 #include "mbed.h"
MightyPork 0:a81364d9a67b 2 #include "neopixel.h"
MightyPork 0:a81364d9a67b 3
MightyPork 0:a81364d9a67b 4 NeoPixelOut::NeoPixelOut(PinName pin) : DigitalOut(pin)
MightyPork 0:a81364d9a67b 5 {
MightyPork 0:a81364d9a67b 6 normalize = false;
MightyPork 0:a81364d9a67b 7 global_scale = 1.0f;
MightyPork 0:a81364d9a67b 8 }
MightyPork 0:a81364d9a67b 9
MightyPork 0:a81364d9a67b 10 // The timing should be approximately 800ns/300ns, 300ns/800ns
MightyPork 0:a81364d9a67b 11 void NeoPixelOut::byte(register uint32_t byte)
MightyPork 0:a81364d9a67b 12 {
MightyPork 0:a81364d9a67b 13 for (int i = 0; i < 8; i++) {
MightyPork 0:a81364d9a67b 14 gpio_write(&gpio, 1);
MightyPork 0:a81364d9a67b 15
MightyPork 0:a81364d9a67b 16 // duty cycle determines bit value
MightyPork 0:a81364d9a67b 17 if (byte & 0x80) {
MightyPork 0:a81364d9a67b 18 // one
tichise 1:415459e3f93b 19 for(int j = 0; j < 6; j++) __NOP();
MightyPork 0:a81364d9a67b 20
MightyPork 0:a81364d9a67b 21 gpio_write(&gpio, 0);
tichise 1:415459e3f93b 22 for(int j = 0; j < 2; j++) __NOP();
MightyPork 0:a81364d9a67b 23 }
MightyPork 0:a81364d9a67b 24 else {
MightyPork 0:a81364d9a67b 25 // zero
tichise 1:415459e3f93b 26 for(int j = 0; j < 2; j++) __NOP();
MightyPork 0:a81364d9a67b 27
MightyPork 0:a81364d9a67b 28 gpio_write(&gpio, 0);
tichise 1:415459e3f93b 29 for(int j = 0; j < 5; j++) __NOP();
MightyPork 0:a81364d9a67b 30 }
MightyPork 0:a81364d9a67b 31
MightyPork 0:a81364d9a67b 32 byte = byte << 1; // shift to next bit
MightyPork 0:a81364d9a67b 33 }
MightyPork 0:a81364d9a67b 34
MightyPork 0:a81364d9a67b 35 }
MightyPork 0:a81364d9a67b 36
MightyPork 0:a81364d9a67b 37 void NeoPixelOut::send(Pixel *colors, uint32_t count, bool flipwait)
MightyPork 0:a81364d9a67b 38 {
MightyPork 0:a81364d9a67b 39 // Disable interrupts in the critical section
MightyPork 0:a81364d9a67b 40 __disable_irq();
MightyPork 0:a81364d9a67b 41
MightyPork 0:a81364d9a67b 42 Pixel* rgb;
MightyPork 0:a81364d9a67b 43 float fr,fg,fb;
MightyPork 0:a81364d9a67b 44 for (int i = 0; i < count; i++) {
MightyPork 0:a81364d9a67b 45 rgb = colors++;
MightyPork 0:a81364d9a67b 46 fr = (int)rgb->r;
MightyPork 0:a81364d9a67b 47 fg = (int)rgb->g;
MightyPork 0:a81364d9a67b 48 fb = (int)rgb->b;
MightyPork 0:a81364d9a67b 49
MightyPork 0:a81364d9a67b 50 if (normalize) {
MightyPork 0:a81364d9a67b 51 float scale = 255.0f/(fr+fg+fb);
MightyPork 0:a81364d9a67b 52 fr *= scale;
MightyPork 0:a81364d9a67b 53 fg *= scale;
MightyPork 0:a81364d9a67b 54 fb *= scale;
MightyPork 0:a81364d9a67b 55 }
MightyPork 0:a81364d9a67b 56
MightyPork 0:a81364d9a67b 57 fr *= global_scale;
MightyPork 0:a81364d9a67b 58 fg *= global_scale;
MightyPork 0:a81364d9a67b 59 fb *= global_scale;
MightyPork 0:a81364d9a67b 60
MightyPork 0:a81364d9a67b 61 if (fr > 255) fr = 255;
MightyPork 0:a81364d9a67b 62 if (fg > 255) fg = 255;
MightyPork 0:a81364d9a67b 63 if (fb > 255) fb = 255;
MightyPork 0:a81364d9a67b 64 if (fr < 0) fr = 0;
MightyPork 0:a81364d9a67b 65 if (fg < 0) fg = 0;
MightyPork 0:a81364d9a67b 66 if (fb < 0) fb = 0;
MightyPork 0:a81364d9a67b 67
MightyPork 0:a81364d9a67b 68 // Black magic to fix distorted timing
MightyPork 0:a81364d9a67b 69 #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE
MightyPork 0:a81364d9a67b 70 __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
MightyPork 0:a81364d9a67b 71 #endif
MightyPork 0:a81364d9a67b 72
MightyPork 0:a81364d9a67b 73 byte((int)fg);
MightyPork 0:a81364d9a67b 74 byte((int)fr);
MightyPork 0:a81364d9a67b 75 byte((int)fb);
MightyPork 0:a81364d9a67b 76
MightyPork 0:a81364d9a67b 77 #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE
MightyPork 0:a81364d9a67b 78 __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
MightyPork 0:a81364d9a67b 79 #endif
MightyPork 0:a81364d9a67b 80 }
MightyPork 0:a81364d9a67b 81
MightyPork 0:a81364d9a67b 82 __enable_irq();
MightyPork 0:a81364d9a67b 83
MightyPork 0:a81364d9a67b 84 if (flipwait) flip();
MightyPork 0:a81364d9a67b 85 }
MightyPork 0:a81364d9a67b 86
MightyPork 0:a81364d9a67b 87
MightyPork 0:a81364d9a67b 88 void NeoPixelOut::flip(void)
MightyPork 0:a81364d9a67b 89 {
MightyPork 0:a81364d9a67b 90 wait_us(50);
MightyPork 0:a81364d9a67b 91 }