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