TLIGHT_PRODUCTS / WS281X
Committer:
mutech
Date:
Fri Aug 26 22:18:43 2016 +0000
Revision:
23:d4061c4b6238
Parent:
22:0846aefbeeae
Child:
24:f93a61e727a3
WS2811/WS2812 Library;

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 0:dff187a80020 19 */
mutech 0:dff187a80020 20
mutech 0:dff187a80020 21 #include "WS281X.h"
mutech 6:5aff0da4b663 22 #if defined(TARGET_STM)
mutech 0:dff187a80020 23 #include "pinmap.h"
mutech 6:5aff0da4b663 24 #endif
mutech 0:dff187a80020 25
mutech 4:4af895bb2979 26 // TARGET_STM32F7
mutech 0:dff187a80020 27 // TARGET_DISCO_F746NG
mutech 0:dff187a80020 28 // TARGET_NUCLEO_F746ZG
mutech 4:4af895bb2979 29 // TARGET_STM32F0
mutech 0:dff187a80020 30 // TARGET_NUCLEO_F030R8
mutech 0:dff187a80020 31 // TARGET_NUCLEO_F070RB
mutech 17:55c563d45bfa 32 // TARGET_NUCLEO_F072RB
mutech 4:4af895bb2979 33 // TARGET_LPC82X
mutech 0:dff187a80020 34 // TARGET_LPC824
mutech 0:dff187a80020 35
mutech 0:dff187a80020 36 //----------------------------------------------------------------------------
mutech 20:28fe0d0d081b 37 WS281X::WS281X(PinName wirePin, PinMode pinMode, int maxPixels, RGBOrder rgbOrder)
mutech 9:087006b19049 38 : _wirePin(wirePin), _gpio(), _buf_owner(false)
mutech 9:087006b19049 39 {
mutech 9:087006b19049 40 gpio_init_inout(&_gpio, wirePin, PIN_OUTPUT, pinMode, 0);
mutech 9:087006b19049 41 #if defined(TARGET_STM)
mutech 9:087006b19049 42 pin_mode_ex(wirePin, pinMode);
mutech 9:087006b19049 43 #endif
mutech 9:087006b19049 44
mutech 9:087006b19049 45 setRGBOrder(rgbOrder);
mutech 9:087006b19049 46 _dummyPixel = 0;
mutech 20:28fe0d0d081b 47 setPixelBuffer(0, maxPixels);
mutech 9:087006b19049 48 }
mutech 9:087006b19049 49
mutech 9:087006b19049 50 WS281X::WS281X(PinName wirePin, PinMode pinMode,
mutech 20:28fe0d0d081b 51 RGBColor *Buffer, int maxPixels, RGBOrder rgbOrder)
mutech 9:087006b19049 52 : _wirePin(wirePin), _gpio(), _buf_owner(false)
mutech 0:dff187a80020 53 {
mutech 0:dff187a80020 54 gpio_init_inout(&_gpio, wirePin, PIN_OUTPUT, pinMode, 0);
mutech 0:dff187a80020 55 #if defined(TARGET_STM)
mutech 0:dff187a80020 56 pin_mode_ex(wirePin, pinMode);
mutech 0:dff187a80020 57 #endif
mutech 0:dff187a80020 58
mutech 0:dff187a80020 59 setRGBOrder(rgbOrder);
mutech 0:dff187a80020 60 _dummyPixel = 0;
mutech 20:28fe0d0d081b 61 setPixelBuffer(Buffer, maxPixels);
mutech 0:dff187a80020 62 }
mutech 0:dff187a80020 63
mutech 0:dff187a80020 64 WS281X::~WS281X()
mutech 0:dff187a80020 65 {
mutech 9:087006b19049 66 if (_buf_owner && _pixels)
mutech 9:087006b19049 67 delete[] _pixels;
mutech 9:087006b19049 68 }
mutech 9:087006b19049 69
mutech 20:28fe0d0d081b 70 void WS281X::setPixelBuffer(RGBColor *Buffer, int maxPixels)
mutech 9:087006b19049 71 {
mutech 9:087006b19049 72 if (_buf_owner && _pixels)
mutech 0:dff187a80020 73 delete[] _pixels;
mutech 9:087006b19049 74
mutech 9:087006b19049 75 _buf_owner = false;
mutech 9:087006b19049 76 _pixels = Buffer;
mutech 9:087006b19049 77
mutech 20:28fe0d0d081b 78 _maxPixels = (maxPixels < 0) ? 0 : (maxPixels > MAX_PIXELS) ? MAX_PIXELS : maxPixels;
mutech 20:28fe0d0d081b 79 if (!_pixels && _maxPixels > 0)
mutech 9:087006b19049 80 {
mutech 20:28fe0d0d081b 81 _pixels = new RGBColor[_maxPixels];
mutech 9:087006b19049 82 _buf_owner = true;
mutech 9:087006b19049 83 }
mutech 20:28fe0d0d081b 84 _numPixels = _maxPixels;
mutech 20:28fe0d0d081b 85 clear();
mutech 20:28fe0d0d081b 86 }
mutech 9:087006b19049 87
mutech 20:28fe0d0d081b 88 void WS281X::setNumPixels(int numPixels)
mutech 20:28fe0d0d081b 89 {
mutech 20:28fe0d0d081b 90 _numPixels = (numPixels < 0) ? 0 : (numPixels > _maxPixels) ? _maxPixels : numPixels;
mutech 0:dff187a80020 91 }
mutech 0:dff187a80020 92
mutech 0:dff187a80020 93 #if defined(TARGET_STM)
mutech 6:5aff0da4b663 94 /**
mutech 6:5aff0da4b663 95 * Configure pin pull-up/pull-down/OpenDrain
mutech 6:5aff0da4b663 96 * typedef enum {
mutech 6:5aff0da4b663 97 * PullNone = 0,
mutech 6:5aff0da4b663 98 * PullUp = 1,
mutech 6:5aff0da4b663 99 * PullDown = 2,
mutech 6:5aff0da4b663 100 * OpenDrain = 3,
mutech 6:5aff0da4b663 101 * PullDefault = PullNone
mutech 6:5aff0da4b663 102 * } PinMode;
mutech 6:5aff0da4b663 103 */
mutech 0:dff187a80020 104 void WS281X::pin_mode_ex(PinName pin, PinMode mode)
mutech 0:dff187a80020 105 {
mutech 6:5aff0da4b663 106 int port_index = STM_PORT(pin);
mutech 6:5aff0da4b663 107 int pin_index = STM_PIN(pin);
mutech 6:5aff0da4b663 108 int offset = pin_index << 1;
mutech 6:5aff0da4b663 109 GPIO_TypeDef * port_reg = ((GPIO_TypeDef *) (GPIOA_BASE + (port_index << 10)));
mutech 6:5aff0da4b663 110
mutech 6:5aff0da4b663 111 // Configure pull-up/pull-down resistors
mutech 6:5aff0da4b663 112 uint32_t pupd = (uint32_t)mode & 3;
mutech 6:5aff0da4b663 113 if (pupd > 2)
mutech 6:5aff0da4b663 114 pupd = 0; // Open-drain = No pull-up/No pull-down
mutech 6:5aff0da4b663 115
mutech 0:dff187a80020 116 if (mode == OpenDrain)
mutech 0:dff187a80020 117 {
mutech 6:5aff0da4b663 118 port_reg->PUPDR &= ~(0x3 << offset); // Open-drain = No pull-up/No pull-down
mutech 6:5aff0da4b663 119 port_reg->OTYPER |= 1 << pin_index;
mutech 0:dff187a80020 120 }
mutech 0:dff187a80020 121 else
mutech 6:5aff0da4b663 122 {
mutech 6:5aff0da4b663 123 port_reg->OTYPER &= ~(1 << pin_index);
mutech 6:5aff0da4b663 124 // pin_mode(pin, mode);
mutech 6:5aff0da4b663 125 port_reg->PUPDR &= ~(0x3 << offset);
mutech 6:5aff0da4b663 126 port_reg->PUPDR |= (mode & 0x03) << offset;
mutech 6:5aff0da4b663 127 }
mutech 0:dff187a80020 128 }
mutech 0:dff187a80020 129 #endif
mutech 0:dff187a80020 130
mutech 0:dff187a80020 131 void WS281X::setRGBOrder(RGBOrder rgbOrder)
mutech 0:dff187a80020 132 {
mutech 0:dff187a80020 133 _rgbOrder = rgbOrder;
mutech 0:dff187a80020 134 switch(_rgbOrder)
mutech 0:dff187a80020 135 {
mutech 6:5aff0da4b663 136 case RGB: _1st = 0; _2nd = 1; _3rd = 2; break;
mutech 6:5aff0da4b663 137 case RBG: _1st = 0; _2nd = 2; _3rd = 1; break;
mutech 6:5aff0da4b663 138 case GRB: _1st = 1; _2nd = 0; _3rd = 2; break;
mutech 6:5aff0da4b663 139 case GBR: _1st = 2; _2nd = 0; _3rd = 1; break;
mutech 6:5aff0da4b663 140 case BRG: _1st = 1; _2nd = 2; _3rd = 0; break;
mutech 6:5aff0da4b663 141 case BGR: _1st = 2; _2nd = 1; _3rd = 0; break;
mutech 6:5aff0da4b663 142 default: _1st = 0; _2nd = 1; _3rd = 2; break;
mutech 0:dff187a80020 143 }
mutech 0:dff187a80020 144 }
mutech 0:dff187a80020 145
mutech 17:55c563d45bfa 146 //#define _nop1() __nop()
mutech 19:48ac403f172f 147 #define _nop1() do {asm volatile ("nop"); } while(0)
mutech 17:55c563d45bfa 148 #define _nop2() _nop1(); _nop1()
mutech 0:dff187a80020 149 #define _nop3() _nop1(); _nop2()
mutech 0:dff187a80020 150 #define _nop4() _nop2(); _nop2()
mutech 0:dff187a80020 151 #define _nop5() _nop1(); _nop4()
mutech 0:dff187a80020 152 #define _nop6() _nop2(); _nop4()
mutech 0:dff187a80020 153 #define _nop7() _nop3(); _nop4()
mutech 0:dff187a80020 154 #define _nop8() _nop4(); _nop4()
mutech 0:dff187a80020 155 #define _nop9() _nop1(); _nop8()
mutech 0:dff187a80020 156 #define _nop10() _nop2(); _nop8()
mutech 0:dff187a80020 157 #define _nop11() _nop3(); _nop8()
mutech 0:dff187a80020 158 #define _nop12() _nop4(); _nop8()
mutech 0:dff187a80020 159 #define _nop13() _nop5(); _nop8()
mutech 0:dff187a80020 160 #define _nop14() _nop6(); _nop8()
mutech 0:dff187a80020 161 #define _nop15() _nop7(); _nop8()
mutech 0:dff187a80020 162 #define _nop16() _nop8(); _nop8()
mutech 0:dff187a80020 163
mutech 4:4af895bb2979 164 #if defined(TARGET_LPC82X)
mutech 5:8e6835a94e10 165 // LPCXpresso824-MAX (30MHz)
mutech 0:dff187a80020 166 #define DELAY_T0H() do{ _nop2(); }while(0)
mutech 0:dff187a80020 167 #define DELAY_T1H() do{ _nop6(); }while(0)
mutech 0:dff187a80020 168 #define DELAY_TLOW() do{ _nop6(); }while(0)
mutech 0:dff187a80020 169 #define DELAY_TLOW2() //do{ _nop2(); }while(0)
mutech 4:4af895bb2979 170 #define DELAY_SPACE() do{ _nop4(); }while(0)
mutech 4:4af895bb2979 171 #define DELAY_NEXT() //do{ _nop1(); }while(0)
mutech 0:dff187a80020 172 #endif
mutech 0:dff187a80020 173
mutech 0:dff187a80020 174 #if defined(TARGET_STM32F0)
mutech 5:8e6835a94e10 175 // NUCLEO-F030R8 (48MHz)
mutech 5:8e6835a94e10 176 // NUCLEO-F070RB (48MHz)
mutech 23:d4061c4b6238 177 // NUCLEO-F072RB (48MHz)
mutech 0:dff187a80020 178 #define DELAY_T0H() do{ _nop8(); _nop4(); }while(0)
mutech 0:dff187a80020 179 #define DELAY_T1H() do{ _nop8(); _nop8(); }while(0)
mutech 0:dff187a80020 180 #define DELAY_TLOW() do{ _nop16(); }while(0)
mutech 0:dff187a80020 181 #define DELAY_TLOW2() //do{ _nop8(); _nop4(); }while(0)
mutech 4:4af895bb2979 182 #define DELAY_SPACE() do{ _nop8(); _nop6(); }while(0)
mutech 4:4af895bb2979 183 #define DELAY_NEXT() do{ _nop8(); }while(0)
mutech 0:dff187a80020 184 #endif
mutech 0:dff187a80020 185
mutech 6:5aff0da4b663 186 #if defined(TARGET_NUCLEO_F446RE)
mutech 6:5aff0da4b663 187 // NUCLEO-F446RE (180MHz)
mutech 6:5aff0da4b663 188 #define USE_DELAYFUNC 1
mutech 6:5aff0da4b663 189 #define T0H (18)
mutech 6:5aff0da4b663 190 #define T0L (58-T0H)
mutech 6:5aff0da4b663 191 #define T1H (40)
mutech 6:5aff0da4b663 192 #define T1L (58-T1H)
mutech 6:5aff0da4b663 193
mutech 6:5aff0da4b663 194 #define DELAY_T0H() _delay(T0H)
mutech 6:5aff0da4b663 195 #define DELAY_T1H() _delay(T1H-T0H)
mutech 6:5aff0da4b663 196 #define DELAY_TLOW() _delay(T1L)
mutech 6:5aff0da4b663 197 #define DELAY_TLOW2() //DELAY_TLOW()
mutech 6:5aff0da4b663 198 #define DELAY_SPACE() _delay(T1L-2)
mutech 6:5aff0da4b663 199 #define DELAY_NEXT() _delay(16)
mutech 6:5aff0da4b663 200 #endif
mutech 6:5aff0da4b663 201
mutech 4:4af895bb2979 202 #if defined(TARGET_NUCLEO_F746ZG)
mutech 4:4af895bb2979 203 // NUCLEO-F746ZG (216MHz)
mutech 6:5aff0da4b663 204 #define USE_DELAYFUNC 1
mutech 0:dff187a80020 205 #define T0H (35)
mutech 5:8e6835a94e10 206 #define T0L (130-T0H)
mutech 4:4af895bb2979 207 #define T1H (75)
mutech 5:8e6835a94e10 208 #define T1L (130-T1H)
mutech 0:dff187a80020 209
mutech 0:dff187a80020 210 #define DELAY_T0H() _delay(T0H)
mutech 0:dff187a80020 211 #define DELAY_T1H() _delay(T1H-T0H)
mutech 0:dff187a80020 212 #define DELAY_TLOW() _delay(T1L)
mutech 0:dff187a80020 213 #define DELAY_TLOW2() //DELAY_TLOW()
mutech 5:8e6835a94e10 214 #define DELAY_SPACE() _delay(T1L+20)
mutech 4:4af895bb2979 215 #define DELAY_NEXT() _delay(50)
mutech 4:4af895bb2979 216 #endif
mutech 0:dff187a80020 217
mutech 4:4af895bb2979 218 #if defined(TARGET_DISCO_F746NG)
mutech 4:4af895bb2979 219 // TARGET_DISCO_F746NG (216MHz)
mutech 6:5aff0da4b663 220 #define USE_DELAYFUNC 1
mutech 4:4af895bb2979 221 #define T0H (35)
mutech 6:5aff0da4b663 222 #define T0L (125-T0H)
mutech 6:5aff0da4b663 223 #define T1H (90)
mutech 6:5aff0da4b663 224 #define T1L (125-T1H)
mutech 4:4af895bb2979 225
mutech 4:4af895bb2979 226 #define DELAY_T0H() _delay(T0H)
mutech 4:4af895bb2979 227 #define DELAY_T1H() _delay(T1H-T0H)
mutech 4:4af895bb2979 228 #define DELAY_TLOW() _delay(T1L)
mutech 4:4af895bb2979 229 #define DELAY_TLOW2() //DELAY_TLOW()
mutech 6:5aff0da4b663 230 #define DELAY_SPACE() _delay(T1L-5)
mutech 6:5aff0da4b663 231 #define DELAY_NEXT() _delay(40)
mutech 4:4af895bb2979 232 #endif
mutech 4:4af895bb2979 233
mutech 6:5aff0da4b663 234 #if defined(USE_DELAYFUNC) && (USE_DELAYFUNC != 0)
mutech 6:5aff0da4b663 235 static inline __attribute__((always_inline))
mutech 6:5aff0da4b663 236 void _delay(int value)
mutech 0:dff187a80020 237 {
mutech 22:0846aefbeeae 238 do { _nop1(); } while (--value);
mutech 0:dff187a80020 239 }
mutech 0:dff187a80020 240 #endif
mutech 0:dff187a80020 241
mutech 0:dff187a80020 242 inline __attribute__((always_inline))
mutech 0:dff187a80020 243 void WS281X::writeByte(__IO regsize_t *reg_set, __IO regsize_t *reg_clr, regsize_t *mask, uint8_t value)
mutech 0:dff187a80020 244 {
mutech 0:dff187a80020 245 do
mutech 0:dff187a80020 246 {
mutech 6:5aff0da4b663 247 #if 1
mutech 0:dff187a80020 248 // bit7
mutech 0:dff187a80020 249 *reg_set = mask[0];
mutech 0:dff187a80020 250 DELAY_T0H();
mutech 0:dff187a80020 251 *reg_clr = mask[(value >> 7) & 1];
mutech 0:dff187a80020 252 DELAY_T1H();
mutech 0:dff187a80020 253 *reg_clr = mask[0];
mutech 0:dff187a80020 254 DELAY_TLOW();
mutech 0:dff187a80020 255
mutech 0:dff187a80020 256 // bit6
mutech 0:dff187a80020 257 *reg_set = mask[0];
mutech 0:dff187a80020 258 DELAY_T0H();
mutech 0:dff187a80020 259 *reg_clr = mask[(value >> 6) & 1];
mutech 0:dff187a80020 260 DELAY_T1H();
mutech 0:dff187a80020 261 *reg_clr = mask[0];
mutech 0:dff187a80020 262 DELAY_TLOW();
mutech 0:dff187a80020 263
mutech 0:dff187a80020 264 // bit5
mutech 0:dff187a80020 265 *reg_set = mask[0];
mutech 0:dff187a80020 266 DELAY_T0H();
mutech 0:dff187a80020 267 *reg_clr = mask[(value >> 5) & 1];
mutech 0:dff187a80020 268 DELAY_T1H();
mutech 0:dff187a80020 269 *reg_clr = mask[0];
mutech 0:dff187a80020 270 DELAY_TLOW();
mutech 0:dff187a80020 271
mutech 0:dff187a80020 272 // bit4
mutech 0:dff187a80020 273 *reg_set = mask[0];
mutech 0:dff187a80020 274 DELAY_T0H();
mutech 0:dff187a80020 275 *reg_clr = mask[(value >> 4) & 1];
mutech 0:dff187a80020 276 DELAY_T1H();
mutech 0:dff187a80020 277 *reg_clr = mask[0];
mutech 0:dff187a80020 278 DELAY_TLOW();
mutech 6:5aff0da4b663 279 #endif
mutech 0:dff187a80020 280
mutech 0:dff187a80020 281 // bit3
mutech 0:dff187a80020 282 *reg_set = mask[0];
mutech 0:dff187a80020 283 DELAY_T0H();
mutech 0:dff187a80020 284 *reg_clr = mask[(value >> 3) & 1];
mutech 0:dff187a80020 285 DELAY_T1H();
mutech 0:dff187a80020 286 *reg_clr = mask[0];
mutech 0:dff187a80020 287 DELAY_TLOW();
mutech 0:dff187a80020 288
mutech 0:dff187a80020 289 // bit2
mutech 0:dff187a80020 290 *reg_set = mask[0];
mutech 0:dff187a80020 291 DELAY_T0H();
mutech 0:dff187a80020 292 *reg_clr = mask[(value >> 2) & 1];
mutech 0:dff187a80020 293 DELAY_T1H();
mutech 0:dff187a80020 294 *reg_clr = mask[0];
mutech 0:dff187a80020 295 DELAY_TLOW();
mutech 0:dff187a80020 296
mutech 0:dff187a80020 297 // bit1
mutech 0:dff187a80020 298 *reg_set = mask[0];
mutech 0:dff187a80020 299 DELAY_T0H();
mutech 0:dff187a80020 300 *reg_clr = mask[(value >> 1) & 1];
mutech 0:dff187a80020 301 DELAY_T1H();
mutech 0:dff187a80020 302 *reg_clr = mask[0];
mutech 0:dff187a80020 303 DELAY_TLOW();
mutech 0:dff187a80020 304
mutech 0:dff187a80020 305 // bit0
mutech 0:dff187a80020 306 *reg_set = mask[0];
mutech 0:dff187a80020 307 DELAY_T0H();
mutech 0:dff187a80020 308 *reg_clr = mask[(value >> 0) & 1];
mutech 0:dff187a80020 309 DELAY_T1H();
mutech 0:dff187a80020 310 *reg_clr = mask[0];
mutech 0:dff187a80020 311 DELAY_TLOW2();
mutech 0:dff187a80020 312
mutech 0:dff187a80020 313 } while (0);
mutech 0:dff187a80020 314 }
mutech 0:dff187a80020 315
mutech 0:dff187a80020 316 void WS281X::show()
mutech 0:dff187a80020 317 {
mutech 0:dff187a80020 318 // CPU_FREQ = 30MHz -> 0.0333us/cycle
mutech 0:dff187a80020 319 // WS2811 0: 0.25us+1.0us, 1: 1.0us+0.25us
mutech 0:dff187a80020 320 // WS2812 0: 0.45us+0.8us, 1: 0.8us+0.45us
mutech 0:dff187a80020 321
mutech 9:087006b19049 322 if (!_pixels)
mutech 9:087006b19049 323 return;
mutech 9:087006b19049 324
mutech 0:dff187a80020 325 #if defined(TARGET_NXP)
mutech 0:dff187a80020 326 __IO uint32_t *reg_set = _gpio.reg_set;
mutech 0:dff187a80020 327 __IO uint32_t *reg_clr = _gpio.reg_clr;
mutech 0:dff187a80020 328 uint32_t mask[2] = { _gpio.mask, 0 };
mutech 0:dff187a80020 329 #elif defined(TARGET_STM32F0) || defined(TARGET_STM32F1)
mutech 0:dff187a80020 330 __IO uint32_t *reg_set = _gpio.reg_set;
mutech 0:dff187a80020 331 __IO uint32_t *reg_clr = _gpio.reg_clr;
mutech 0:dff187a80020 332 uint32_t mask[2] = { _gpio.mask, 0 };
mutech 0:dff187a80020 333 #elif defined(TARGET_STM)
mutech 0:dff187a80020 334 __IO uint16_t *reg_set = (__IO uint16_t *)_gpio.reg_set_clr;
mutech 0:dff187a80020 335 __IO uint16_t *reg_clr = reg_set + 1;
mutech 0:dff187a80020 336 uint16_t mask[2] = { _gpio.mask, 0 };
mutech 0:dff187a80020 337 #endif
mutech 0:dff187a80020 338
mutech 0:dff187a80020 339 uint8_t *pix = (uint8_t *)_pixels;
mutech 0:dff187a80020 340 uint8_t *end = pix + (_numPixels * sizeof(_pixels[0]));
mutech 0:dff187a80020 341
mutech 0:dff187a80020 342 __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up.
mutech 0:dff187a80020 343
mutech 0:dff187a80020 344 uint8_t value;
mutech 0:dff187a80020 345 do
mutech 0:dff187a80020 346 {
mutech 0:dff187a80020 347 value = pix[_1st];
mutech 0:dff187a80020 348 writeByte(reg_set, reg_clr, mask, value);
mutech 0:dff187a80020 349 DELAY_SPACE();
mutech 0:dff187a80020 350
mutech 0:dff187a80020 351 value = pix[_2nd];
mutech 0:dff187a80020 352 writeByte(reg_set, reg_clr, mask, value);
mutech 0:dff187a80020 353 DELAY_SPACE();
mutech 0:dff187a80020 354
mutech 0:dff187a80020 355 value = pix[_3rd];
mutech 0:dff187a80020 356 writeByte(reg_set, reg_clr, mask, value);
mutech 0:dff187a80020 357 pix += sizeof(_pixels[0]);
mutech 0:dff187a80020 358 DELAY_NEXT();
mutech 0:dff187a80020 359 } while (pix < end);
mutech 0:dff187a80020 360
mutech 0:dff187a80020 361 __enable_irq(); // Re-enable interrupts now that we are done.
mutech 0:dff187a80020 362
mutech 0:dff187a80020 363 wait_us(50);
mutech 0:dff187a80020 364 }
mutech 0:dff187a80020 365
mutech 8:0617f524d67d 366 // 指定位置のピクセルへ色配列を指定サイズ分をコピーする
mutech 8:0617f524d67d 367 void WS281X::setColor(int index, RGBColor *color, int len)
mutech 8:0617f524d67d 368 {
mutech 22:0846aefbeeae 369 if (_pixels && len > 0 && (uint16_t)index < _numPixels)
mutech 22:0846aefbeeae 370 {
mutech 22:0846aefbeeae 371 if (index + len > _numPixels)
mutech 22:0846aefbeeae 372 len = _numPixels - index;
mutech 22:0846aefbeeae 373 memcpy(&_pixels[index], color, len * sizeof(_pixels[0]));
mutech 22:0846aefbeeae 374 }
mutech 21:77275089d837 375 }
mutech 21:77275089d837 376
mutech 21:77275089d837 377 void WS281X::setColor(int index, HSVColor *color, int len)
mutech 21:77275089d837 378 {
mutech 22:0846aefbeeae 379 if (_pixels && len > 0 && (uint16_t)index < _numPixels)
mutech 8:0617f524d67d 380 {
mutech 22:0846aefbeeae 381 if (index + len > _numPixels)
mutech 22:0846aefbeeae 382 len = _numPixels - index;
mutech 22:0846aefbeeae 383 do
mutech 22:0846aefbeeae 384 {
mutech 22:0846aefbeeae 385 _pixels[index] = *color;
mutech 22:0846aefbeeae 386 ++index;
mutech 22:0846aefbeeae 387 ++color;
mutech 22:0846aefbeeae 388 } while (--len);
mutech 22:0846aefbeeae 389 }
mutech 8:0617f524d67d 390 }
mutech 8:0617f524d67d 391
mutech 8:0617f524d67d 392 // 指定位置のピクセルから指定色を指定サイズ分書き込む
mutech 8:0617f524d67d 393 void WS281X::fillColor(int index, const RGBColor color, int len)
mutech 8:0617f524d67d 394 {
mutech 9:087006b19049 395 if (!_pixels || len < 1 || (uint16_t)index >= _numPixels)
mutech 8:0617f524d67d 396 return;
mutech 8:0617f524d67d 397 if (index + len > _numPixels)
mutech 8:0617f524d67d 398 len = _numPixels - index;
mutech 8:0617f524d67d 399 do
mutech 8:0617f524d67d 400 {
mutech 8:0617f524d67d 401 _pixels[index] = color;
mutech 8:0617f524d67d 402 ++index;
mutech 8:0617f524d67d 403 } while (--len);
mutech 8:0617f524d67d 404 }
mutech 8:0617f524d67d 405
mutech 0:dff187a80020 406 // 先頭から指定サイズ分のブロックをバッファの最後までコピーする
mutech 0:dff187a80020 407 void WS281X::repeatBlock(int block_size)
mutech 0:dff187a80020 408 {
mutech 22:0846aefbeeae 409 if (_pixels && block_size > 0 && block_size < _numPixels)
mutech 0:dff187a80020 410 {
mutech 22:0846aefbeeae 411 RGBColor *dest = _pixels + block_size;
mutech 22:0846aefbeeae 412 int left = _numPixels - block_size;
mutech 22:0846aefbeeae 413 while (left > block_size)
mutech 22:0846aefbeeae 414 {
mutech 22:0846aefbeeae 415 memcpy(dest, _pixels, block_size * sizeof(_pixels[0]));
mutech 22:0846aefbeeae 416 dest += block_size;
mutech 22:0846aefbeeae 417 left -= block_size;
mutech 22:0846aefbeeae 418 block_size <<= 1; // 次回は2倍のサイズの転送
mutech 22:0846aefbeeae 419 }
mutech 22:0846aefbeeae 420 memcpy(dest, _pixels, left * sizeof(_pixels[0]));
mutech 0:dff187a80020 421 }
mutech 0:dff187a80020 422 }
mutech 0:dff187a80020 423
mutech 0:dff187a80020 424 // 指定色でバッファを埋める
mutech 8:0617f524d67d 425 void WS281X::clear(const RGBColor color)
mutech 0:dff187a80020 426 {
mutech 9:087006b19049 427 if (_pixels)
mutech 9:087006b19049 428 {
mutech 9:087006b19049 429 _pixels[0] = color;
mutech 9:087006b19049 430 repeatBlock(1);
mutech 9:087006b19049 431 }
mutech 0:dff187a80020 432 }
mutech 0:dff187a80020 433
mutech 0:dff187a80020 434 // 指定色でバッファを埋めた後表示
mutech 8:0617f524d67d 435 void WS281X::show(const RGBColor color)
mutech 0:dff187a80020 436 {
mutech 0:dff187a80020 437 clear(color);
mutech 0:dff187a80020 438 show();
mutech 0:dff187a80020 439 }
mutech 0:dff187a80020 440
mutech 0:dff187a80020 441 //----------------------------------------------------------------------------