TLIGHT_PRODUCTS / WS281X
Committer:
mutech
Date:
Fri Dec 16 23:29:34 2016 +0000
Revision:
44:d89e5c59aeb0
Parent:
36:0fe7917a832a
Child:
46:2374900f8845
WS2811/WS2812 Driver

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mutech 0:dff187a80020 1 /* WS281X.cpp (for LPC82X/STM32F0x/STM32F746xx)
mutech 0:dff187a80020 2 * mbed Microcontroller Library
mutech 0:dff187a80020 3 * Copyright (c) 2016 muetch, t.kuroki, MIT License
mutech 0:dff187a80020 4 *
mutech 0:dff187a80020 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
mutech 0:dff187a80020 6 * and associated documentation files (the "Software"), to deal in the Software without restriction,
mutech 0:dff187a80020 7 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
mutech 0:dff187a80020 8 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
mutech 0:dff187a80020 9 * furnished to do so, subject to the following conditions:
mutech 0:dff187a80020 10 *
mutech 0:dff187a80020 11 * The above copyright notice and this permission notice shall be included in all copies or
mutech 0:dff187a80020 12 * substantial portions of the Software.
mutech 0:dff187a80020 13 *
mutech 0:dff187a80020 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
mutech 0:dff187a80020 15 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
mutech 0:dff187a80020 16 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
mutech 0:dff187a80020 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mutech 0:dff187a80020 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mutech 27:bc79f444883b 19 *
mutech 27:bc79f444883b 20 * Rev 0.97 2016-09-07
mutech 28:b452e097da53 21 * Rev 0.98 2016-09-08
mutech 0:dff187a80020 22 */
mutech 0:dff187a80020 23
mutech 0:dff187a80020 24 #include "WS281X.h"
mutech 6:5aff0da4b663 25 #if defined(TARGET_STM)
mutech 0:dff187a80020 26 #include "pinmap.h"
mutech 6:5aff0da4b663 27 #endif
mutech 0:dff187a80020 28
mutech 32:64c391617f6c 29 #define USE_MALLOC 1 // 0:new, 1:malloc
mutech 32:64c391617f6c 30
mutech 4:4af895bb2979 31 // TARGET_STM32F7
mutech 0:dff187a80020 32 // TARGET_DISCO_F746NG
mutech 0:dff187a80020 33 // TARGET_NUCLEO_F746ZG
mutech 35:dffa06d09fdc 34 // TARGET_NUCLEO_F446RE
mutech 4:4af895bb2979 35 // TARGET_STM32F0
mutech 0:dff187a80020 36 // TARGET_NUCLEO_F030R8
mutech 0:dff187a80020 37 // TARGET_NUCLEO_F070RB
mutech 17:55c563d45bfa 38 // TARGET_NUCLEO_F072RB
mutech 35:dffa06d09fdc 39 // TARGET_NUCLEO_F091RC
mutech 4:4af895bb2979 40 // TARGET_LPC82X
mutech 0:dff187a80020 41 // TARGET_LPC824
mutech 0:dff187a80020 42
mutech 0:dff187a80020 43 //----------------------------------------------------------------------------
mutech 27:bc79f444883b 44 // 指定されたバッファの先頭からblock_size分をbuf_sizeが満杯になるまで繰り返しコピーする
mutech 27:bc79f444883b 45 template <class T>
mutech 27:bc79f444883b 46 static void repeat_buffer(T *buffer, int buf_size, int block_size = 1)
mutech 27:bc79f444883b 47 {
mutech 27:bc79f444883b 48 if (buffer && block_size > 0 && (uint16_t)block_size < buf_size)
mutech 27:bc79f444883b 49 {
mutech 27:bc79f444883b 50 T *dest = buffer + block_size;
mutech 27:bc79f444883b 51 int left = buf_size - block_size;
mutech 27:bc79f444883b 52 while (left > block_size)
mutech 27:bc79f444883b 53 {
mutech 27:bc79f444883b 54 memcpy(dest, buffer, block_size * sizeof(T));
mutech 27:bc79f444883b 55 dest += block_size;
mutech 27:bc79f444883b 56 left -= block_size;
mutech 27:bc79f444883b 57 block_size <<= 1; // 次回は2倍のサイズの転送
mutech 27:bc79f444883b 58 }
mutech 27:bc79f444883b 59 memcpy(dest, buffer, left * sizeof(T));
mutech 27:bc79f444883b 60 }
mutech 27:bc79f444883b 61 }
mutech 27:bc79f444883b 62
mutech 27:bc79f444883b 63 //----------------------------------------------------------------------------
mutech 28:b452e097da53 64 WS281X::WS281X(PinName wirePin, PinMode pinMode, int maxPixels, RGBOrder order)
mutech 32:64c391617f6c 65 : _wirePin(wirePin), _gpio(), _owned_buffer(false)
mutech 9:087006b19049 66 {
mutech 9:087006b19049 67 gpio_init_inout(&_gpio, wirePin, PIN_OUTPUT, pinMode, 0);
mutech 9:087006b19049 68 #if defined(TARGET_STM)
mutech 9:087006b19049 69 pin_mode_ex(wirePin, pinMode);
mutech 9:087006b19049 70 #endif
mutech 9:087006b19049 71
mutech 28:b452e097da53 72 rgbOrder(order);
mutech 9:087006b19049 73 _dummyPixel = 0;
mutech 20:28fe0d0d081b 74 setPixelBuffer(0, maxPixels);
mutech 9:087006b19049 75 }
mutech 9:087006b19049 76
mutech 9:087006b19049 77 WS281X::WS281X(PinName wirePin, PinMode pinMode,
mutech 28:b452e097da53 78 RGBColor *buffer, int maxPixels, RGBOrder order)
mutech 32:64c391617f6c 79 : _wirePin(wirePin), _gpio(), _owned_buffer(false)
mutech 0:dff187a80020 80 {
mutech 0:dff187a80020 81 gpio_init_inout(&_gpio, wirePin, PIN_OUTPUT, pinMode, 0);
mutech 0:dff187a80020 82 #if defined(TARGET_STM)
mutech 0:dff187a80020 83 pin_mode_ex(wirePin, pinMode);
mutech 0:dff187a80020 84 #endif
mutech 0:dff187a80020 85
mutech 28:b452e097da53 86 rgbOrder(order);
mutech 0:dff187a80020 87 _dummyPixel = 0;
mutech 27:bc79f444883b 88 setPixelBuffer(buffer, maxPixels);
mutech 0:dff187a80020 89 }
mutech 0:dff187a80020 90
mutech 0:dff187a80020 91 WS281X::~WS281X()
mutech 0:dff187a80020 92 {
mutech 32:64c391617f6c 93 setPixelBuffer(0, 0);
mutech 9:087006b19049 94 }
mutech 9:087006b19049 95
mutech 27:bc79f444883b 96 void WS281X::setPixelBuffer(RGBColor *buffer, int maxPixels)
mutech 9:087006b19049 97 {
mutech 32:64c391617f6c 98 if (_owned_buffer && _pixels)
mutech 32:64c391617f6c 99 {
mutech 32:64c391617f6c 100 #if USE_MALLOC
mutech 32:64c391617f6c 101 free(_pixels);
mutech 32:64c391617f6c 102 #else
mutech 0:dff187a80020 103 delete[] _pixels;
mutech 32:64c391617f6c 104 #endif
mutech 32:64c391617f6c 105 }
mutech 32:64c391617f6c 106 _owned_buffer = false;
mutech 32:64c391617f6c 107 _maxPixels = (maxPixels < 0) ? 0 : (maxPixels > MAX_PIXELS) ? MAX_PIXELS : maxPixels;
mutech 32:64c391617f6c 108 _pixels = (!_maxPixels) ? NULL : buffer;
mutech 9:087006b19049 109
mutech 20:28fe0d0d081b 110 if (!_pixels && _maxPixels > 0)
mutech 9:087006b19049 111 {
mutech 32:64c391617f6c 112 #if USE_MALLOC
mutech 32:64c391617f6c 113 _pixels = static_cast<RGBColor*>(malloc(sizeof(RGBColor)*_maxPixels));
mutech 32:64c391617f6c 114 if (_pixels)
mutech 32:64c391617f6c 115 _owned_buffer = true;
mutech 32:64c391617f6c 116 else
mutech 32:64c391617f6c 117 _maxPixels = 0;
mutech 32:64c391617f6c 118 #else
mutech 20:28fe0d0d081b 119 _pixels = new RGBColor[_maxPixels];
mutech 32:64c391617f6c 120 _owned_buffer = true;
mutech 32:64c391617f6c 121 #endif
mutech 9:087006b19049 122 }
mutech 20:28fe0d0d081b 123 _numPixels = _maxPixels;
mutech 20:28fe0d0d081b 124 clear();
mutech 20:28fe0d0d081b 125 }
mutech 9:087006b19049 126
mutech 27:bc79f444883b 127 int WS281X::numPixels(int value)
mutech 20:28fe0d0d081b 128 {
mutech 27:bc79f444883b 129 if (value >= 0)
mutech 27:bc79f444883b 130 _numPixels = (value > _maxPixels) ? _maxPixels : value;
mutech 27:bc79f444883b 131 return _numPixels;
mutech 0:dff187a80020 132 }
mutech 0:dff187a80020 133
mutech 0:dff187a80020 134 #if defined(TARGET_STM)
mutech 6:5aff0da4b663 135 /**
mutech 6:5aff0da4b663 136 * Configure pin pull-up/pull-down/OpenDrain
mutech 6:5aff0da4b663 137 * typedef enum {
mutech 6:5aff0da4b663 138 * PullNone = 0,
mutech 6:5aff0da4b663 139 * PullUp = 1,
mutech 6:5aff0da4b663 140 * PullDown = 2,
mutech 6:5aff0da4b663 141 * OpenDrain = 3,
mutech 6:5aff0da4b663 142 * PullDefault = PullNone
mutech 6:5aff0da4b663 143 * } PinMode;
mutech 6:5aff0da4b663 144 */
mutech 0:dff187a80020 145 void WS281X::pin_mode_ex(PinName pin, PinMode mode)
mutech 0:dff187a80020 146 {
mutech 6:5aff0da4b663 147 int port_index = STM_PORT(pin);
mutech 6:5aff0da4b663 148 int pin_index = STM_PIN(pin);
mutech 6:5aff0da4b663 149 int offset = pin_index << 1;
mutech 6:5aff0da4b663 150 GPIO_TypeDef * port_reg = ((GPIO_TypeDef *) (GPIOA_BASE + (port_index << 10)));
mutech 6:5aff0da4b663 151
mutech 6:5aff0da4b663 152 // Configure pull-up/pull-down resistors
mutech 6:5aff0da4b663 153 uint32_t pupd = (uint32_t)mode & 3;
mutech 6:5aff0da4b663 154 if (pupd > 2)
mutech 6:5aff0da4b663 155 pupd = 0; // Open-drain = No pull-up/No pull-down
mutech 6:5aff0da4b663 156
mutech 0:dff187a80020 157 if (mode == OpenDrain)
mutech 0:dff187a80020 158 {
mutech 6:5aff0da4b663 159 port_reg->PUPDR &= ~(0x3 << offset); // Open-drain = No pull-up/No pull-down
mutech 6:5aff0da4b663 160 port_reg->OTYPER |= 1 << pin_index;
mutech 0:dff187a80020 161 }
mutech 0:dff187a80020 162 else
mutech 6:5aff0da4b663 163 {
mutech 6:5aff0da4b663 164 port_reg->OTYPER &= ~(1 << pin_index);
mutech 6:5aff0da4b663 165 // pin_mode(pin, mode);
mutech 6:5aff0da4b663 166 port_reg->PUPDR &= ~(0x3 << offset);
mutech 6:5aff0da4b663 167 port_reg->PUPDR |= (mode & 0x03) << offset;
mutech 6:5aff0da4b663 168 }
mutech 0:dff187a80020 169 }
mutech 0:dff187a80020 170 #endif
mutech 0:dff187a80020 171
mutech 28:b452e097da53 172 WS281X::RGBOrder WS281X::rgbOrder(WS281X::RGBOrder order)
mutech 0:dff187a80020 173 {
mutech 29:a362df191524 174 if (order != READ_ORDER)
mutech 0:dff187a80020 175 {
mutech 29:a362df191524 176 _rgbOrder = order;
mutech 29:a362df191524 177 switch(order)
mutech 29:a362df191524 178 {
mutech 29:a362df191524 179 case RGB: _1st = 0; _2nd = 1; _3rd = 2; break; // WS2811
mutech 29:a362df191524 180 case RBG: _1st = 0; _2nd = 2; _3rd = 1; break;
mutech 29:a362df191524 181 case GRB: _1st = 1; _2nd = 0; _3rd = 2; break; // WS2812
mutech 29:a362df191524 182 case GBR: _1st = 2; _2nd = 0; _3rd = 1; break;
mutech 29:a362df191524 183 case BRG: _1st = 1; _2nd = 2; _3rd = 0; break;
mutech 29:a362df191524 184 case BGR: _1st = 2; _2nd = 1; _3rd = 0; break;
mutech 29:a362df191524 185 default:
mutech 29:a362df191524 186 _1st = 0; _2nd = 1; _3rd = 2;
mutech 29:a362df191524 187 _rgbOrder = GRB; // WS2812
mutech 29:a362df191524 188 break;
mutech 29:a362df191524 189 }
mutech 0:dff187a80020 190 }
mutech 28:b452e097da53 191 return _rgbOrder;
mutech 0:dff187a80020 192 }
mutech 0:dff187a80020 193
mutech 17:55c563d45bfa 194 //#define _nop1() __nop()
mutech 19:48ac403f172f 195 #define _nop1() do {asm volatile ("nop"); } while(0)
mutech 17:55c563d45bfa 196 #define _nop2() _nop1(); _nop1()
mutech 0:dff187a80020 197 #define _nop3() _nop1(); _nop2()
mutech 0:dff187a80020 198 #define _nop4() _nop2(); _nop2()
mutech 0:dff187a80020 199 #define _nop5() _nop1(); _nop4()
mutech 0:dff187a80020 200 #define _nop6() _nop2(); _nop4()
mutech 0:dff187a80020 201 #define _nop7() _nop3(); _nop4()
mutech 0:dff187a80020 202 #define _nop8() _nop4(); _nop4()
mutech 0:dff187a80020 203 #define _nop9() _nop1(); _nop8()
mutech 0:dff187a80020 204 #define _nop10() _nop2(); _nop8()
mutech 0:dff187a80020 205 #define _nop11() _nop3(); _nop8()
mutech 0:dff187a80020 206 #define _nop12() _nop4(); _nop8()
mutech 0:dff187a80020 207 #define _nop13() _nop5(); _nop8()
mutech 0:dff187a80020 208 #define _nop14() _nop6(); _nop8()
mutech 0:dff187a80020 209 #define _nop15() _nop7(); _nop8()
mutech 0:dff187a80020 210 #define _nop16() _nop8(); _nop8()
mutech 0:dff187a80020 211
mutech 4:4af895bb2979 212 #if defined(TARGET_LPC82X)
mutech 5:8e6835a94e10 213 // LPCXpresso824-MAX (30MHz)
mutech 0:dff187a80020 214 #define DELAY_T0H() do{ _nop2(); }while(0)
mutech 0:dff187a80020 215 #define DELAY_T1H() do{ _nop6(); }while(0)
mutech 0:dff187a80020 216 #define DELAY_TLOW() do{ _nop6(); }while(0)
mutech 0:dff187a80020 217 #define DELAY_TLOW2() //do{ _nop2(); }while(0)
mutech 4:4af895bb2979 218 #define DELAY_SPACE() do{ _nop4(); }while(0)
mutech 4:4af895bb2979 219 #define DELAY_NEXT() //do{ _nop1(); }while(0)
mutech 0:dff187a80020 220 #endif
mutech 0:dff187a80020 221
mutech 0:dff187a80020 222 #if defined(TARGET_STM32F0)
mutech 5:8e6835a94e10 223 // NUCLEO-F030R8 (48MHz)
mutech 5:8e6835a94e10 224 // NUCLEO-F070RB (48MHz)
mutech 23:d4061c4b6238 225 // NUCLEO-F072RB (48MHz)
mutech 0:dff187a80020 226 #define DELAY_T0H() do{ _nop8(); _nop4(); }while(0)
mutech 0:dff187a80020 227 #define DELAY_T1H() do{ _nop8(); _nop8(); }while(0)
mutech 0:dff187a80020 228 #define DELAY_TLOW() do{ _nop16(); }while(0)
mutech 0:dff187a80020 229 #define DELAY_TLOW2() //do{ _nop8(); _nop4(); }while(0)
mutech 4:4af895bb2979 230 #define DELAY_SPACE() do{ _nop8(); _nop6(); }while(0)
mutech 4:4af895bb2979 231 #define DELAY_NEXT() do{ _nop8(); }while(0)
mutech 0:dff187a80020 232 #endif
mutech 0:dff187a80020 233
mutech 44:d89e5c59aeb0 234 #if defined(TARGET_NUCLEO_F411RE)
mutech 44:d89e5c59aeb0 235 // NUCLEO-F411RE (96MHz)
mutech 44:d89e5c59aeb0 236 #define USE_DELAYFUNC 1
mutech 44:d89e5c59aeb0 237 #define T0H (10)
mutech 44:d89e5c59aeb0 238 #define T0L (31-T0H)
mutech 44:d89e5c59aeb0 239 #define T1H (21)
mutech 44:d89e5c59aeb0 240 #define T1L (31-T1H)
mutech 44:d89e5c59aeb0 241
mutech 44:d89e5c59aeb0 242 #define DELAY_T0H() _delay(T0H)
mutech 44:d89e5c59aeb0 243 #define DELAY_T1H() _delay(T1H-T0H)
mutech 44:d89e5c59aeb0 244 #define DELAY_TLOW() _delay(T1L)
mutech 44:d89e5c59aeb0 245 #define DELAY_TLOW2() //DELAY_TLOW()
mutech 44:d89e5c59aeb0 246 #define DELAY_SPACE() _delay(T1L-2)
mutech 44:d89e5c59aeb0 247 #define DELAY_NEXT() _delay(16)
mutech 44:d89e5c59aeb0 248 #endif
mutech 44:d89e5c59aeb0 249
mutech 6:5aff0da4b663 250 #if defined(TARGET_NUCLEO_F446RE)
mutech 6:5aff0da4b663 251 // NUCLEO-F446RE (180MHz)
mutech 6:5aff0da4b663 252 #define USE_DELAYFUNC 1
mutech 6:5aff0da4b663 253 #define T0H (18)
mutech 6:5aff0da4b663 254 #define T0L (58-T0H)
mutech 6:5aff0da4b663 255 #define T1H (40)
mutech 6:5aff0da4b663 256 #define T1L (58-T1H)
mutech 6:5aff0da4b663 257
mutech 6:5aff0da4b663 258 #define DELAY_T0H() _delay(T0H)
mutech 6:5aff0da4b663 259 #define DELAY_T1H() _delay(T1H-T0H)
mutech 6:5aff0da4b663 260 #define DELAY_TLOW() _delay(T1L)
mutech 6:5aff0da4b663 261 #define DELAY_TLOW2() //DELAY_TLOW()
mutech 6:5aff0da4b663 262 #define DELAY_SPACE() _delay(T1L-2)
mutech 6:5aff0da4b663 263 #define DELAY_NEXT() _delay(16)
mutech 6:5aff0da4b663 264 #endif
mutech 6:5aff0da4b663 265
mutech 4:4af895bb2979 266 #if defined(TARGET_NUCLEO_F746ZG)
mutech 4:4af895bb2979 267 // NUCLEO-F746ZG (216MHz)
mutech 6:5aff0da4b663 268 #define USE_DELAYFUNC 1
mutech 0:dff187a80020 269 #define T0H (35)
mutech 5:8e6835a94e10 270 #define T0L (130-T0H)
mutech 4:4af895bb2979 271 #define T1H (75)
mutech 5:8e6835a94e10 272 #define T1L (130-T1H)
mutech 0:dff187a80020 273
mutech 0:dff187a80020 274 #define DELAY_T0H() _delay(T0H)
mutech 0:dff187a80020 275 #define DELAY_T1H() _delay(T1H-T0H)
mutech 0:dff187a80020 276 #define DELAY_TLOW() _delay(T1L)
mutech 0:dff187a80020 277 #define DELAY_TLOW2() //DELAY_TLOW()
mutech 5:8e6835a94e10 278 #define DELAY_SPACE() _delay(T1L+20)
mutech 4:4af895bb2979 279 #define DELAY_NEXT() _delay(50)
mutech 4:4af895bb2979 280 #endif
mutech 0:dff187a80020 281
mutech 4:4af895bb2979 282 #if defined(TARGET_DISCO_F746NG)
mutech 4:4af895bb2979 283 // TARGET_DISCO_F746NG (216MHz)
mutech 6:5aff0da4b663 284 #define USE_DELAYFUNC 1
mutech 4:4af895bb2979 285 #define T0H (35)
mutech 6:5aff0da4b663 286 #define T0L (125-T0H)
mutech 6:5aff0da4b663 287 #define T1H (90)
mutech 6:5aff0da4b663 288 #define T1L (125-T1H)
mutech 4:4af895bb2979 289
mutech 4:4af895bb2979 290 #define DELAY_T0H() _delay(T0H)
mutech 4:4af895bb2979 291 #define DELAY_T1H() _delay(T1H-T0H)
mutech 4:4af895bb2979 292 #define DELAY_TLOW() _delay(T1L)
mutech 4:4af895bb2979 293 #define DELAY_TLOW2() //DELAY_TLOW()
mutech 6:5aff0da4b663 294 #define DELAY_SPACE() _delay(T1L-5)
mutech 6:5aff0da4b663 295 #define DELAY_NEXT() _delay(40)
mutech 4:4af895bb2979 296 #endif
mutech 4:4af895bb2979 297
mutech 6:5aff0da4b663 298 #if defined(USE_DELAYFUNC) && (USE_DELAYFUNC != 0)
mutech 6:5aff0da4b663 299 static inline __attribute__((always_inline))
mutech 6:5aff0da4b663 300 void _delay(int value)
mutech 0:dff187a80020 301 {
mutech 22:0846aefbeeae 302 do { _nop1(); } while (--value);
mutech 0:dff187a80020 303 }
mutech 0:dff187a80020 304 #endif
mutech 0:dff187a80020 305
mutech 0:dff187a80020 306 inline __attribute__((always_inline))
mutech 0:dff187a80020 307 void WS281X::writeByte(__IO regsize_t *reg_set, __IO regsize_t *reg_clr, regsize_t *mask, uint8_t value)
mutech 0:dff187a80020 308 {
mutech 0:dff187a80020 309 do
mutech 0:dff187a80020 310 {
mutech 6:5aff0da4b663 311 #if 1
mutech 0:dff187a80020 312 // bit7
mutech 0:dff187a80020 313 *reg_set = mask[0];
mutech 0:dff187a80020 314 DELAY_T0H();
mutech 0:dff187a80020 315 *reg_clr = mask[(value >> 7) & 1];
mutech 0:dff187a80020 316 DELAY_T1H();
mutech 0:dff187a80020 317 *reg_clr = mask[0];
mutech 0:dff187a80020 318 DELAY_TLOW();
mutech 0:dff187a80020 319
mutech 0:dff187a80020 320 // bit6
mutech 0:dff187a80020 321 *reg_set = mask[0];
mutech 0:dff187a80020 322 DELAY_T0H();
mutech 0:dff187a80020 323 *reg_clr = mask[(value >> 6) & 1];
mutech 0:dff187a80020 324 DELAY_T1H();
mutech 0:dff187a80020 325 *reg_clr = mask[0];
mutech 0:dff187a80020 326 DELAY_TLOW();
mutech 0:dff187a80020 327
mutech 0:dff187a80020 328 // bit5
mutech 0:dff187a80020 329 *reg_set = mask[0];
mutech 0:dff187a80020 330 DELAY_T0H();
mutech 0:dff187a80020 331 *reg_clr = mask[(value >> 5) & 1];
mutech 0:dff187a80020 332 DELAY_T1H();
mutech 0:dff187a80020 333 *reg_clr = mask[0];
mutech 0:dff187a80020 334 DELAY_TLOW();
mutech 0:dff187a80020 335
mutech 0:dff187a80020 336 // bit4
mutech 0:dff187a80020 337 *reg_set = mask[0];
mutech 0:dff187a80020 338 DELAY_T0H();
mutech 0:dff187a80020 339 *reg_clr = mask[(value >> 4) & 1];
mutech 0:dff187a80020 340 DELAY_T1H();
mutech 0:dff187a80020 341 *reg_clr = mask[0];
mutech 0:dff187a80020 342 DELAY_TLOW();
mutech 6:5aff0da4b663 343 #endif
mutech 0:dff187a80020 344
mutech 0:dff187a80020 345 // bit3
mutech 0:dff187a80020 346 *reg_set = mask[0];
mutech 0:dff187a80020 347 DELAY_T0H();
mutech 0:dff187a80020 348 *reg_clr = mask[(value >> 3) & 1];
mutech 0:dff187a80020 349 DELAY_T1H();
mutech 0:dff187a80020 350 *reg_clr = mask[0];
mutech 0:dff187a80020 351 DELAY_TLOW();
mutech 0:dff187a80020 352
mutech 0:dff187a80020 353 // bit2
mutech 0:dff187a80020 354 *reg_set = mask[0];
mutech 0:dff187a80020 355 DELAY_T0H();
mutech 0:dff187a80020 356 *reg_clr = mask[(value >> 2) & 1];
mutech 0:dff187a80020 357 DELAY_T1H();
mutech 0:dff187a80020 358 *reg_clr = mask[0];
mutech 0:dff187a80020 359 DELAY_TLOW();
mutech 0:dff187a80020 360
mutech 0:dff187a80020 361 // bit1
mutech 0:dff187a80020 362 *reg_set = mask[0];
mutech 0:dff187a80020 363 DELAY_T0H();
mutech 0:dff187a80020 364 *reg_clr = mask[(value >> 1) & 1];
mutech 0:dff187a80020 365 DELAY_T1H();
mutech 0:dff187a80020 366 *reg_clr = mask[0];
mutech 0:dff187a80020 367 DELAY_TLOW();
mutech 0:dff187a80020 368
mutech 0:dff187a80020 369 // bit0
mutech 0:dff187a80020 370 *reg_set = mask[0];
mutech 0:dff187a80020 371 DELAY_T0H();
mutech 0:dff187a80020 372 *reg_clr = mask[(value >> 0) & 1];
mutech 0:dff187a80020 373 DELAY_T1H();
mutech 0:dff187a80020 374 *reg_clr = mask[0];
mutech 0:dff187a80020 375 DELAY_TLOW2();
mutech 0:dff187a80020 376
mutech 0:dff187a80020 377 } while (0);
mutech 0:dff187a80020 378 }
mutech 0:dff187a80020 379
mutech 0:dff187a80020 380 void WS281X::show()
mutech 0:dff187a80020 381 {
mutech 0:dff187a80020 382 // CPU_FREQ = 30MHz -> 0.0333us/cycle
mutech 0:dff187a80020 383 // WS2811 0: 0.25us+1.0us, 1: 1.0us+0.25us
mutech 0:dff187a80020 384 // WS2812 0: 0.45us+0.8us, 1: 0.8us+0.45us
mutech 0:dff187a80020 385
mutech 9:087006b19049 386 if (!_pixels)
mutech 9:087006b19049 387 return;
mutech 9:087006b19049 388
mutech 0:dff187a80020 389 #if defined(TARGET_NXP)
mutech 0:dff187a80020 390 __IO uint32_t *reg_set = _gpio.reg_set;
mutech 0:dff187a80020 391 __IO uint32_t *reg_clr = _gpio.reg_clr;
mutech 0:dff187a80020 392 uint32_t mask[2] = { _gpio.mask, 0 };
mutech 0:dff187a80020 393 #elif defined(TARGET_STM32F0) || defined(TARGET_STM32F1)
mutech 0:dff187a80020 394 __IO uint32_t *reg_set = _gpio.reg_set;
mutech 0:dff187a80020 395 __IO uint32_t *reg_clr = _gpio.reg_clr;
mutech 0:dff187a80020 396 uint32_t mask[2] = { _gpio.mask, 0 };
mutech 0:dff187a80020 397 #elif defined(TARGET_STM)
mutech 0:dff187a80020 398 __IO uint16_t *reg_set = (__IO uint16_t *)_gpio.reg_set_clr;
mutech 0:dff187a80020 399 __IO uint16_t *reg_clr = reg_set + 1;
mutech 0:dff187a80020 400 uint16_t mask[2] = { _gpio.mask, 0 };
mutech 0:dff187a80020 401 #endif
mutech 0:dff187a80020 402
mutech 0:dff187a80020 403 uint8_t *pix = (uint8_t *)_pixels;
mutech 0:dff187a80020 404 uint8_t *end = pix + (_numPixels * sizeof(_pixels[0]));
mutech 0:dff187a80020 405
mutech 0:dff187a80020 406 __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up.
mutech 0:dff187a80020 407
mutech 0:dff187a80020 408 uint8_t value;
mutech 0:dff187a80020 409 do
mutech 0:dff187a80020 410 {
mutech 0:dff187a80020 411 value = pix[_1st];
mutech 0:dff187a80020 412 writeByte(reg_set, reg_clr, mask, value);
mutech 0:dff187a80020 413 DELAY_SPACE();
mutech 0:dff187a80020 414
mutech 0:dff187a80020 415 value = pix[_2nd];
mutech 0:dff187a80020 416 writeByte(reg_set, reg_clr, mask, value);
mutech 0:dff187a80020 417 DELAY_SPACE();
mutech 0:dff187a80020 418
mutech 0:dff187a80020 419 value = pix[_3rd];
mutech 0:dff187a80020 420 writeByte(reg_set, reg_clr, mask, value);
mutech 0:dff187a80020 421 pix += sizeof(_pixels[0]);
mutech 0:dff187a80020 422 DELAY_NEXT();
mutech 0:dff187a80020 423 } while (pix < end);
mutech 0:dff187a80020 424
mutech 0:dff187a80020 425 __enable_irq(); // Re-enable interrupts now that we are done.
mutech 0:dff187a80020 426
mutech 0:dff187a80020 427 wait_us(50);
mutech 0:dff187a80020 428 }
mutech 0:dff187a80020 429
mutech 8:0617f524d67d 430 // 指定位置のピクセルへ色配列を指定サイズ分をコピーする
mutech 27:bc79f444883b 431 void WS281X::setPixels(int index, RGBColor *color, int len)
mutech 8:0617f524d67d 432 {
mutech 35:dffa06d09fdc 433 int numPixels = static_cast<int>(_numPixels);
mutech 35:dffa06d09fdc 434 if (_pixels && len > 0 && index < numPixels && (index + len) >= 0)
mutech 22:0846aefbeeae 435 {
mutech 34:5a141ed5d52a 436 if (index < 0)
mutech 34:5a141ed5d52a 437 {
mutech 35:dffa06d09fdc 438 len += index;
mutech 35:dffa06d09fdc 439 color -= index;
mutech 35:dffa06d09fdc 440 index = 0;
mutech 34:5a141ed5d52a 441 }
mutech 35:dffa06d09fdc 442 if (index + len > numPixels)
mutech 35:dffa06d09fdc 443 len = numPixels - index;
mutech 22:0846aefbeeae 444 memcpy(&_pixels[index], color, len * sizeof(_pixels[0]));
mutech 22:0846aefbeeae 445 }
mutech 21:77275089d837 446 }
mutech 21:77275089d837 447
mutech 27:bc79f444883b 448 void WS281X::setPixels(int index, HSVColor *color, int len)
mutech 21:77275089d837 449 {
mutech 35:dffa06d09fdc 450 int numPixels = static_cast<int>(_numPixels);
mutech 35:dffa06d09fdc 451 if (_pixels && len > 0 && index < numPixels && (index + len) >= 0)
mutech 8:0617f524d67d 452 {
mutech 34:5a141ed5d52a 453 if (index < 0)
mutech 34:5a141ed5d52a 454 {
mutech 35:dffa06d09fdc 455 len += index;
mutech 35:dffa06d09fdc 456 color -= index;
mutech 35:dffa06d09fdc 457 index = 0;
mutech 34:5a141ed5d52a 458 }
mutech 35:dffa06d09fdc 459 if (index + len > numPixels)
mutech 35:dffa06d09fdc 460 len = numPixels - index;
mutech 24:f93a61e727a3 461 RGBColor *dest = &_pixels[index];
mutech 22:0846aefbeeae 462 do
mutech 22:0846aefbeeae 463 {
mutech 24:f93a61e727a3 464 *dest++ = *color++;
mutech 22:0846aefbeeae 465 } while (--len);
mutech 22:0846aefbeeae 466 }
mutech 8:0617f524d67d 467 }
mutech 8:0617f524d67d 468
mutech 27:bc79f444883b 469 // 指定色を指定位置のピクセルから指定サイズ分書き込む
mutech 28:b452e097da53 470 void WS281X::fillPixels(int index, const RGBColor color, int len)
mutech 8:0617f524d67d 471 {
mutech 36:0fe7917a832a 472 int numPixels = static_cast<int>(_numPixels);
mutech 36:0fe7917a832a 473 if (_pixels && len > 0 && index < numPixels && (index + len) >= 0)
mutech 8:0617f524d67d 474 {
mutech 36:0fe7917a832a 475 if (index < 0)
mutech 36:0fe7917a832a 476 {
mutech 36:0fe7917a832a 477 len += index;
mutech 36:0fe7917a832a 478 index = 0;
mutech 36:0fe7917a832a 479 }
mutech 36:0fe7917a832a 480 if (index + len > numPixels)
mutech 36:0fe7917a832a 481 len = numPixels - index;
mutech 27:bc79f444883b 482 _pixels[index] = color;
mutech 27:bc79f444883b 483 repeat_buffer<RGBColor>(_pixels + index, len, 1);
mutech 24:f93a61e727a3 484 }
mutech 8:0617f524d67d 485 }
mutech 8:0617f524d67d 486
mutech 27:bc79f444883b 487 // 指定位置のピクセルから指定色を指定サイズ分書き込む
mutech 28:b452e097da53 488 void WS281X::fillPixels(int index, const HSVColor color, int len)
mutech 27:bc79f444883b 489 {
mutech 28:b452e097da53 490 fillPixels(index, color, len);
mutech 27:bc79f444883b 491 }
mutech 27:bc79f444883b 492
mutech 0:dff187a80020 493 // 先頭から指定サイズ分のブロックをバッファの最後までコピーする
mutech 27:bc79f444883b 494 void WS281X::repeatPixels(int block_size)
mutech 0:dff187a80020 495 {
mutech 22:0846aefbeeae 496 if (_pixels && block_size > 0 && block_size < _numPixels)
mutech 0:dff187a80020 497 {
mutech 27:bc79f444883b 498 repeat_buffer<RGBColor>(_pixels, _numPixels, block_size);
mutech 0:dff187a80020 499 }
mutech 0:dff187a80020 500 }
mutech 0:dff187a80020 501
mutech 27:bc79f444883b 502 void WS281X::repeatPixels(RGBColor *source, int size)
mutech 24:f93a61e727a3 503 {
mutech 24:f93a61e727a3 504 if (_pixels && source && size > 0)
mutech 24:f93a61e727a3 505 {
mutech 24:f93a61e727a3 506 if (size > _numPixels)
mutech 24:f93a61e727a3 507 size = _numPixels;
mutech 24:f93a61e727a3 508 memcpy(_pixels, source, size * sizeof(_pixels[0]));
mutech 27:bc79f444883b 509 repeat_buffer<RGBColor>(_pixels, _numPixels, size);
mutech 24:f93a61e727a3 510 }
mutech 24:f93a61e727a3 511 }
mutech 24:f93a61e727a3 512
mutech 27:bc79f444883b 513 void WS281X::repeatPixels(HSVColor *source, int size)
mutech 24:f93a61e727a3 514 {
mutech 24:f93a61e727a3 515 if (_pixels && source && size > 0)
mutech 24:f93a61e727a3 516 {
mutech 24:f93a61e727a3 517 if (size > _numPixels)
mutech 24:f93a61e727a3 518 size = _numPixels;
mutech 24:f93a61e727a3 519 for (int i = 0; i < size; ++i)
mutech 24:f93a61e727a3 520 _pixels[i] = *source++;
mutech 27:bc79f444883b 521 repeat_buffer<RGBColor>(_pixels, _numPixels, size);
mutech 9:087006b19049 522 }
mutech 0:dff187a80020 523 }
mutech 0:dff187a80020 524
mutech 28:b452e097da53 525 void WS281X::makeGradation(int index, RGBColor from, RGBColor to, int len)
mutech 28:b452e097da53 526 {
mutech 28:b452e097da53 527 if (!_pixels || len < 1 || index >= _numPixels || (index + len) < 0)
mutech 28:b452e097da53 528 return;
mutech 28:b452e097da53 529
mutech 28:b452e097da53 530 int end = len;
mutech 28:b452e097da53 531 if (index + end > _numPixels)
mutech 28:b452e097da53 532 end = _numPixels - index;
mutech 28:b452e097da53 533
mutech 28:b452e097da53 534 RGBColor color;
mutech 28:b452e097da53 535 RGBColor *dest = _pixels;
mutech 28:b452e097da53 536 if (index > 0)
mutech 28:b452e097da53 537 dest += index;
mutech 28:b452e097da53 538 for (int i = (index < 0) ? -index : 0; i < end; ++i)
mutech 28:b452e097da53 539 {
mutech 28:b452e097da53 540 int j = len - i;
mutech 28:b452e097da53 541 color.red = ((from.red * j) + (to.red * i)) / len;
mutech 28:b452e097da53 542 color.green = ((from.green * j) + (to.green * i)) / len;
mutech 28:b452e097da53 543 color.blue = ((from.blue * j) + (to.blue * i)) / len;
mutech 28:b452e097da53 544 *dest++ = GammaColor(color);
mutech 28:b452e097da53 545 }
mutech 28:b452e097da53 546 }
mutech 28:b452e097da53 547
mutech 28:b452e097da53 548 void WS281X::makeRainbow(int index, HSVColor color, int len, int direction)
mutech 28:b452e097da53 549 {
mutech 28:b452e097da53 550 if (!_pixels || len < 1 || index >= _numPixels || (index + len) < 0)
mutech 28:b452e097da53 551 return;
mutech 28:b452e097da53 552
mutech 28:b452e097da53 553 int end = len;
mutech 28:b452e097da53 554 if (index + end > _numPixels)
mutech 28:b452e097da53 555 end = _numPixels - index;
mutech 28:b452e097da53 556
mutech 28:b452e097da53 557 HSVColor hsv(color);
mutech 28:b452e097da53 558 RGBColor *dest = _pixels;
mutech 28:b452e097da53 559 if (index > 0)
mutech 28:b452e097da53 560 dest += index;
mutech 28:b452e097da53 561 direction = (direction >= 0) ? -3600 : 3600;
mutech 28:b452e097da53 562 for (int i = (index < 0) ? -index : 0; i < end; ++i)
mutech 28:b452e097da53 563 {
mutech 28:b452e097da53 564 hsv.hue = color.hue + direction * i / len;
mutech 28:b452e097da53 565 *dest++ = GammaColor(hsv);
mutech 28:b452e097da53 566 }
mutech 28:b452e097da53 567 }
mutech 28:b452e097da53 568
mutech 0:dff187a80020 569 // 指定色でバッファを埋めた後表示
mutech 8:0617f524d67d 570 void WS281X::show(const RGBColor color)
mutech 0:dff187a80020 571 {
mutech 0:dff187a80020 572 clear(color);
mutech 0:dff187a80020 573 show();
mutech 0:dff187a80020 574 }
mutech 0:dff187a80020 575
mutech 0:dff187a80020 576 //----------------------------------------------------------------------------