明石高専ロボ研 mbedライブラリ
Dependencies: mbed
neopixel.cpp@14:7ea663f79c81, 2022-03-05 (annotated)
- Committer:
- darkumatar
- Date:
- Sat Mar 05 05:00:50 2022 +0000
- Revision:
- 14:7ea663f79c81
- Parent:
- 11:eaf2e3166d20
a
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
TanakaRobo | 0:ca84ed7518f5 | 1 | #include "mbed.h" |
TanakaRobo | 0:ca84ed7518f5 | 2 | #include "neopixel.h" |
TanakaRobo | 0:ca84ed7518f5 | 3 | |
TanakaRobo | 7:4ad54efe2fdd | 4 | #if defined(TARGET_NUCLEO_L432KC) |
TanakaRobo | 7:4ad54efe2fdd | 5 | |
TanakaRobo | 7:4ad54efe2fdd | 6 | #define PIXEL_WAIT_1_ (6) |
TanakaRobo | 7:4ad54efe2fdd | 7 | #define PIXEL_WAIT_2_ (2) |
TanakaRobo | 7:4ad54efe2fdd | 8 | #define PIXEL_WAIT_3_ (2) |
TanakaRobo | 7:4ad54efe2fdd | 9 | #define PIXEL_WAIT_4_ (5) |
TanakaRobo | 7:4ad54efe2fdd | 10 | |
TanakaRobo | 7:4ad54efe2fdd | 11 | #elif defined(TARGET_NUCLEO_F446RE) |
TanakaRobo | 7:4ad54efe2fdd | 12 | |
TanakaRobo | 7:4ad54efe2fdd | 13 | #define PIXEL_WAIT_1_ (9) |
TanakaRobo | 7:4ad54efe2fdd | 14 | #define PIXEL_WAIT_2_ (5) |
TanakaRobo | 7:4ad54efe2fdd | 15 | #define PIXEL_WAIT_3_ (4) |
TanakaRobo | 7:4ad54efe2fdd | 16 | #define PIXEL_WAIT_4_ (9) |
TanakaRobo | 7:4ad54efe2fdd | 17 | |
TanakaRobo | 7:4ad54efe2fdd | 18 | #else |
TanakaRobo | 7:4ad54efe2fdd | 19 | #error "This board is not supported" |
TanakaRobo | 7:4ad54efe2fdd | 20 | #endif |
TanakaRobo | 11:eaf2e3166d20 | 21 | |
TanakaRobo | 5:a7894e6982ea | 22 | NeoPixelOut::NeoPixelOut(PinName pin, int num) : DigitalOut(pin) |
TanakaRobo | 0:ca84ed7518f5 | 23 | { |
TanakaRobo | 0:ca84ed7518f5 | 24 | normalize = false; |
TanakaRobo | 0:ca84ed7518f5 | 25 | global_scale = 1.0f; |
TanakaRobo | 5:a7894e6982ea | 26 | num_pixels_ = num; |
TanakaRobo | 5:a7894e6982ea | 27 | strip_.resize(num); |
TanakaRobo | 0:ca84ed7518f5 | 28 | } |
TanakaRobo | 0:ca84ed7518f5 | 29 | |
TanakaRobo | 0:ca84ed7518f5 | 30 | // The timing should be approximately 800ns/300ns, 300ns/800ns |
TanakaRobo | 0:ca84ed7518f5 | 31 | void NeoPixelOut::byte(register uint32_t byte) |
TanakaRobo | 0:ca84ed7518f5 | 32 | { |
TanakaRobo | 0:ca84ed7518f5 | 33 | for (int i = 0; i < 8; i++) { |
TanakaRobo | 0:ca84ed7518f5 | 34 | gpio_write(&gpio, 1); |
TanakaRobo | 0:ca84ed7518f5 | 35 | |
TanakaRobo | 0:ca84ed7518f5 | 36 | // duty cycle determines bit value |
TanakaRobo | 0:ca84ed7518f5 | 37 | if (byte & 0x80) { |
TanakaRobo | 0:ca84ed7518f5 | 38 | // one |
TanakaRobo | 7:4ad54efe2fdd | 39 | for(int j = 0; j < PIXEL_WAIT_1_; j++) asm("NOP");//6 9 |
TanakaRobo | 0:ca84ed7518f5 | 40 | |
TanakaRobo | 0:ca84ed7518f5 | 41 | gpio_write(&gpio, 0); |
TanakaRobo | 7:4ad54efe2fdd | 42 | for(int j = 0; j < PIXEL_WAIT_2_; j++) asm("NOP");//2 5 |
TanakaRobo | 0:ca84ed7518f5 | 43 | } |
TanakaRobo | 0:ca84ed7518f5 | 44 | else { |
TanakaRobo | 0:ca84ed7518f5 | 45 | // zero |
TanakaRobo | 7:4ad54efe2fdd | 46 | for(int j = 0; j < PIXEL_WAIT_3_; j++) asm("NOP");//2 4 |
TanakaRobo | 0:ca84ed7518f5 | 47 | |
TanakaRobo | 0:ca84ed7518f5 | 48 | gpio_write(&gpio, 0); |
TanakaRobo | 7:4ad54efe2fdd | 49 | for(int j = 0; j < PIXEL_WAIT_4_; j++) asm("NOP");//5 9 |
TanakaRobo | 0:ca84ed7518f5 | 50 | } |
TanakaRobo | 0:ca84ed7518f5 | 51 | |
TanakaRobo | 0:ca84ed7518f5 | 52 | byte = byte << 1; // shift to next bit |
TanakaRobo | 0:ca84ed7518f5 | 53 | } |
TanakaRobo | 0:ca84ed7518f5 | 54 | |
TanakaRobo | 0:ca84ed7518f5 | 55 | } |
TanakaRobo | 0:ca84ed7518f5 | 56 | |
TanakaRobo | 5:a7894e6982ea | 57 | void NeoPixelOut::setPixelColor(uint32_t i,uint32_t color){ |
TanakaRobo | 8:82727add54ce | 58 | if(i < num_pixels_){ |
TanakaRobo | 8:82727add54ce | 59 | strip_[i].hex = color; |
TanakaRobo | 5:a7894e6982ea | 60 | } |
TanakaRobo | 5:a7894e6982ea | 61 | } |
TanakaRobo | 5:a7894e6982ea | 62 | |
TanakaRobo | 5:a7894e6982ea | 63 | void NeoPixelOut::show(){ |
TanakaRobo | 5:a7894e6982ea | 64 | // Disable interrupts in the critical section |
TanakaRobo | 5:a7894e6982ea | 65 | __disable_irq(); |
TanakaRobo | 5:a7894e6982ea | 66 | |
TanakaRobo | 5:a7894e6982ea | 67 | float fr,fg,fb; |
TanakaRobo | 7:4ad54efe2fdd | 68 | for (int i = 0; i < num_pixels_; i++) { |
TanakaRobo | 5:a7894e6982ea | 69 | fr = strip_[i].r; |
TanakaRobo | 5:a7894e6982ea | 70 | fg = strip_[i].g; |
TanakaRobo | 5:a7894e6982ea | 71 | fb = strip_[i].b; |
TanakaRobo | 5:a7894e6982ea | 72 | |
TanakaRobo | 5:a7894e6982ea | 73 | if (normalize) { |
TanakaRobo | 5:a7894e6982ea | 74 | float scale = 255.0f/(fr+fg+fb); |
TanakaRobo | 5:a7894e6982ea | 75 | fr *= scale; |
TanakaRobo | 5:a7894e6982ea | 76 | fg *= scale; |
TanakaRobo | 5:a7894e6982ea | 77 | fb *= scale; |
TanakaRobo | 5:a7894e6982ea | 78 | } |
TanakaRobo | 5:a7894e6982ea | 79 | |
TanakaRobo | 5:a7894e6982ea | 80 | fr *= global_scale; |
TanakaRobo | 5:a7894e6982ea | 81 | fg *= global_scale; |
TanakaRobo | 5:a7894e6982ea | 82 | fb *= global_scale; |
TanakaRobo | 5:a7894e6982ea | 83 | |
TanakaRobo | 5:a7894e6982ea | 84 | if (fr > 255) fr = 255; |
TanakaRobo | 5:a7894e6982ea | 85 | if (fg > 255) fg = 255; |
TanakaRobo | 5:a7894e6982ea | 86 | if (fb > 255) fb = 255; |
TanakaRobo | 5:a7894e6982ea | 87 | if (fr < 0) fr = 0; |
TanakaRobo | 5:a7894e6982ea | 88 | if (fg < 0) fg = 0; |
TanakaRobo | 5:a7894e6982ea | 89 | if (fb < 0) fb = 0; |
TanakaRobo | 5:a7894e6982ea | 90 | |
TanakaRobo | 5:a7894e6982ea | 91 | // Black magic to fix distorted timing |
TanakaRobo | 5:a7894e6982ea | 92 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE |
TanakaRobo | 5:a7894e6982ea | 93 | __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); |
TanakaRobo | 5:a7894e6982ea | 94 | #endif |
TanakaRobo | 5:a7894e6982ea | 95 | |
TanakaRobo | 5:a7894e6982ea | 96 | byte((int)fg); |
TanakaRobo | 5:a7894e6982ea | 97 | byte((int)fr); |
TanakaRobo | 5:a7894e6982ea | 98 | byte((int)fb); |
TanakaRobo | 5:a7894e6982ea | 99 | |
TanakaRobo | 5:a7894e6982ea | 100 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE |
TanakaRobo | 5:a7894e6982ea | 101 | __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); |
TanakaRobo | 5:a7894e6982ea | 102 | #endif |
TanakaRobo | 5:a7894e6982ea | 103 | } |
TanakaRobo | 5:a7894e6982ea | 104 | |
TanakaRobo | 5:a7894e6982ea | 105 | __enable_irq(); |
TanakaRobo | 5:a7894e6982ea | 106 | |
TanakaRobo | 5:a7894e6982ea | 107 | flip(); |
TanakaRobo | 5:a7894e6982ea | 108 | } |
TanakaRobo | 5:a7894e6982ea | 109 | |
TanakaRobo | 0:ca84ed7518f5 | 110 | void NeoPixelOut::send(Pixel *colors, uint32_t count, bool flipwait) |
TanakaRobo | 0:ca84ed7518f5 | 111 | { |
TanakaRobo | 0:ca84ed7518f5 | 112 | // Disable interrupts in the critical section |
TanakaRobo | 0:ca84ed7518f5 | 113 | __disable_irq(); |
TanakaRobo | 0:ca84ed7518f5 | 114 | |
TanakaRobo | 0:ca84ed7518f5 | 115 | Pixel* rgb; |
TanakaRobo | 0:ca84ed7518f5 | 116 | float fr,fg,fb; |
TanakaRobo | 0:ca84ed7518f5 | 117 | for (int i = 0; i < count; i++) { |
TanakaRobo | 0:ca84ed7518f5 | 118 | rgb = colors++; |
TanakaRobo | 0:ca84ed7518f5 | 119 | fr = (int)rgb->r; |
TanakaRobo | 0:ca84ed7518f5 | 120 | fg = (int)rgb->g; |
TanakaRobo | 0:ca84ed7518f5 | 121 | fb = (int)rgb->b; |
TanakaRobo | 0:ca84ed7518f5 | 122 | |
TanakaRobo | 0:ca84ed7518f5 | 123 | if (normalize) { |
TanakaRobo | 0:ca84ed7518f5 | 124 | float scale = 255.0f/(fr+fg+fb); |
TanakaRobo | 0:ca84ed7518f5 | 125 | fr *= scale; |
TanakaRobo | 0:ca84ed7518f5 | 126 | fg *= scale; |
TanakaRobo | 0:ca84ed7518f5 | 127 | fb *= scale; |
TanakaRobo | 0:ca84ed7518f5 | 128 | } |
TanakaRobo | 0:ca84ed7518f5 | 129 | |
TanakaRobo | 0:ca84ed7518f5 | 130 | fr *= global_scale; |
TanakaRobo | 0:ca84ed7518f5 | 131 | fg *= global_scale; |
TanakaRobo | 0:ca84ed7518f5 | 132 | fb *= global_scale; |
TanakaRobo | 0:ca84ed7518f5 | 133 | |
TanakaRobo | 0:ca84ed7518f5 | 134 | if (fr > 255) fr = 255; |
TanakaRobo | 0:ca84ed7518f5 | 135 | if (fg > 255) fg = 255; |
TanakaRobo | 0:ca84ed7518f5 | 136 | if (fb > 255) fb = 255; |
TanakaRobo | 0:ca84ed7518f5 | 137 | if (fr < 0) fr = 0; |
TanakaRobo | 0:ca84ed7518f5 | 138 | if (fg < 0) fg = 0; |
TanakaRobo | 0:ca84ed7518f5 | 139 | if (fb < 0) fb = 0; |
TanakaRobo | 0:ca84ed7518f5 | 140 | |
TanakaRobo | 0:ca84ed7518f5 | 141 | // Black magic to fix distorted timing |
TanakaRobo | 0:ca84ed7518f5 | 142 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE |
TanakaRobo | 0:ca84ed7518f5 | 143 | __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); |
TanakaRobo | 0:ca84ed7518f5 | 144 | #endif |
TanakaRobo | 0:ca84ed7518f5 | 145 | |
TanakaRobo | 0:ca84ed7518f5 | 146 | byte((int)fg); |
TanakaRobo | 0:ca84ed7518f5 | 147 | byte((int)fr); |
TanakaRobo | 0:ca84ed7518f5 | 148 | byte((int)fb); |
TanakaRobo | 0:ca84ed7518f5 | 149 | |
TanakaRobo | 0:ca84ed7518f5 | 150 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE |
TanakaRobo | 0:ca84ed7518f5 | 151 | __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); |
TanakaRobo | 0:ca84ed7518f5 | 152 | #endif |
TanakaRobo | 0:ca84ed7518f5 | 153 | } |
TanakaRobo | 0:ca84ed7518f5 | 154 | |
TanakaRobo | 0:ca84ed7518f5 | 155 | __enable_irq(); |
TanakaRobo | 0:ca84ed7518f5 | 156 | |
TanakaRobo | 0:ca84ed7518f5 | 157 | if (flipwait) flip(); |
TanakaRobo | 0:ca84ed7518f5 | 158 | } |
TanakaRobo | 0:ca84ed7518f5 | 159 | |
TanakaRobo | 8:82727add54ce | 160 | uint32_t NeoPixelOut::color(uint8_t b,uint8_t g,uint8_t r){ |
TanakaRobo | 8:82727add54ce | 161 | return (uint32_t)b + ((uint32_t)g << 8) + ((uint32_t)r << 16); |
TanakaRobo | 5:a7894e6982ea | 162 | } |
TanakaRobo | 5:a7894e6982ea | 163 | |
TanakaRobo | 5:a7894e6982ea | 164 | int NeoPixelOut::numPixels(){ |
TanakaRobo | 5:a7894e6982ea | 165 | return num_pixels_; |
TanakaRobo | 5:a7894e6982ea | 166 | } |
TanakaRobo | 5:a7894e6982ea | 167 | |
TanakaRobo | 5:a7894e6982ea | 168 | void NeoPixelOut::off(bool flag){ |
TanakaRobo | 8:82727add54ce | 169 | for(int i = 0;i < num_pixels_;i++){ |
TanakaRobo | 5:a7894e6982ea | 170 | strip_[i].hex = 0; |
TanakaRobo | 5:a7894e6982ea | 171 | } |
TanakaRobo | 5:a7894e6982ea | 172 | if(flag){ |
TanakaRobo | 5:a7894e6982ea | 173 | show(); |
TanakaRobo | 5:a7894e6982ea | 174 | } |
TanakaRobo | 5:a7894e6982ea | 175 | } |
TanakaRobo | 5:a7894e6982ea | 176 | |
TanakaRobo | 5:a7894e6982ea | 177 | void NeoPixelOut::changeNum(uint32_t num){ |
TanakaRobo | 5:a7894e6982ea | 178 | strip_.resize(num); |
TanakaRobo | 5:a7894e6982ea | 179 | num_pixels_ = num; |
TanakaRobo | 5:a7894e6982ea | 180 | } |
TanakaRobo | 5:a7894e6982ea | 181 | |
TanakaRobo | 5:a7894e6982ea | 182 | void NeoPixelOut::setBrightness(float brightness){ |
TanakaRobo | 5:a7894e6982ea | 183 | global_scale = brightness; |
TanakaRobo | 5:a7894e6982ea | 184 | } |
TanakaRobo | 0:ca84ed7518f5 | 185 | |
TanakaRobo | 0:ca84ed7518f5 | 186 | void NeoPixelOut::flip(void) |
TanakaRobo | 0:ca84ed7518f5 | 187 | { |
TanakaRobo | 0:ca84ed7518f5 | 188 | wait_us(50); |
TanakaRobo | 0:ca84ed7518f5 | 189 | } |