A conversion of the excellent Adafruit WS2801 library for Arduino to work on mbed

Dependents:   SSS_Ble

Committer:
SomeRandomBloke
Date:
Tue Jun 03 20:19:23 2014 +0000
Revision:
4:987c91c45188
Parent:
3:dfffbd9f8ac6
Child:
5:bbe85db83246
re-added delay on hardware spi as not working fully without it

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 0:582e1b9c1cc1 1 #include "mbed.h"
SomeRandomBloke 0:582e1b9c1cc1 2 #include "Adafruit_WS2801.h"
SomeRandomBloke 0:582e1b9c1cc1 3
SomeRandomBloke 3:dfffbd9f8ac6 4
SomeRandomBloke 0:582e1b9c1cc1 5 // Example to control WS2801-based RGB LED Modules in a strand or strip
SomeRandomBloke 0:582e1b9c1cc1 6 // Written by Adafruit - MIT license
SomeRandomBloke 0:582e1b9c1cc1 7 /*****************************************************************************/
SomeRandomBloke 0:582e1b9c1cc1 8
SomeRandomBloke 2:2fdaa13896a4 9 SPI spi(p16, p15, p13); // mosi, miso, sclk
SomeRandomBloke 2:2fdaa13896a4 10
SomeRandomBloke 0:582e1b9c1cc1 11 // Constructor for use with hardware SPI (specific clock/data pins):
SomeRandomBloke 3:dfffbd9f8ac6 12 /*Adafruit_WS2801::Adafruit_WS2801(uint16_t n, uint8_t order): clkpin(PTD4), datapin(PTA12)
SomeRandomBloke 0:582e1b9c1cc1 13 {
SomeRandomBloke 0:582e1b9c1cc1 14 rgb_order = order;
SomeRandomBloke 0:582e1b9c1cc1 15 alloc(n);
SomeRandomBloke 3:dfffbd9f8ac6 16 updatePins();
SomeRandomBloke 3:dfffbd9f8ac6 17 }*/
SomeRandomBloke 3:dfffbd9f8ac6 18
SomeRandomBloke 3:dfffbd9f8ac6 19 // Constructor for use with arbitrary clock/data pins:
SomeRandomBloke 3:dfffbd9f8ac6 20 Adafruit_WS2801::Adafruit_WS2801(int16_t n, PinName dpin, PinName cpin, uint8_t order)
SomeRandomBloke 3:dfffbd9f8ac6 21 : clkpin(cpin), datapin(dpin)
SomeRandomBloke 3:dfffbd9f8ac6 22 {
SomeRandomBloke 3:dfffbd9f8ac6 23 rgb_order = order;
SomeRandomBloke 3:dfffbd9f8ac6 24 alloc(n);
SomeRandomBloke 3:dfffbd9f8ac6 25 width = 1;
SomeRandomBloke 3:dfffbd9f8ac6 26 height = n;
SomeRandomBloke 3:dfffbd9f8ac6 27 hardwareSPI = false;
SomeRandomBloke 0:582e1b9c1cc1 28 // updatePins(dpin, cpin);
SomeRandomBloke 0:582e1b9c1cc1 29 }
SomeRandomBloke 0:582e1b9c1cc1 30
SomeRandomBloke 0:582e1b9c1cc1 31 // Constructor for use with a matrix configuration, specify w, h for size of matrix
SomeRandomBloke 0:582e1b9c1cc1 32 // assumes configuration where string starts at coordinate 0,0 and continues to w-1,0, w-1,1
SomeRandomBloke 0:582e1b9c1cc1 33 // and on to 0,1, 0,2 and on to w-1,2 and so on. Snaking back and forth till the end.
SomeRandomBloke 0:582e1b9c1cc1 34 // other function calls with provide access to pixels via an x,y coordinate system
SomeRandomBloke 3:dfffbd9f8ac6 35 Adafruit_WS2801::Adafruit_WS2801(int16_t w, int16_t h, PinName dpin, PinName cpin, uint8_t order)
SomeRandomBloke 3:dfffbd9f8ac6 36 : clkpin(cpin), datapin(dpin)
SomeRandomBloke 0:582e1b9c1cc1 37 {
SomeRandomBloke 0:582e1b9c1cc1 38 rgb_order = order;
SomeRandomBloke 0:582e1b9c1cc1 39 alloc(w * h);
SomeRandomBloke 0:582e1b9c1cc1 40 width = w;
SomeRandomBloke 0:582e1b9c1cc1 41 height = h;
SomeRandomBloke 3:dfffbd9f8ac6 42 hardwareSPI = false;
SomeRandomBloke 0:582e1b9c1cc1 43 // updatePins(dpin, cpin);
SomeRandomBloke 0:582e1b9c1cc1 44 }
SomeRandomBloke 0:582e1b9c1cc1 45
SomeRandomBloke 0:582e1b9c1cc1 46 // Allocate 3 bytes per pixel, init to RGB 'off' state:
SomeRandomBloke 0:582e1b9c1cc1 47 void Adafruit_WS2801::alloc(uint16_t n)
SomeRandomBloke 0:582e1b9c1cc1 48 {
SomeRandomBloke 0:582e1b9c1cc1 49 begun = false;
SomeRandomBloke 0:582e1b9c1cc1 50 numLEDs = ((pixels = (uint8_t *)calloc(n, 3)) != NULL) ? n : 0;
SomeRandomBloke 3:dfffbd9f8ac6 51 hardwareSPI = true;
SomeRandomBloke 2:2fdaa13896a4 52
SomeRandomBloke 2:2fdaa13896a4 53 // for(int bits = 0; bits <= numLEDs*24; bits++) {
SomeRandomBloke 2:2fdaa13896a4 54 // spi.write(0x00);
SomeRandomBloke 2:2fdaa13896a4 55 // clkpin = 0;
SomeRandomBloke 2:2fdaa13896a4 56 // datapin = 0;
SomeRandomBloke 2:2fdaa13896a4 57 // clkpin = 1;
SomeRandomBloke 2:2fdaa13896a4 58 // }
SomeRandomBloke 2:2fdaa13896a4 59 // clkpin = 0;
SomeRandomBloke 0:582e1b9c1cc1 60 }
SomeRandomBloke 0:582e1b9c1cc1 61
SomeRandomBloke 3:dfffbd9f8ac6 62 // Constructor for use with a matrix configuration, specify w, h for size of matrix
SomeRandomBloke 3:dfffbd9f8ac6 63 // assumes configuration where string starts at coordinate 0,0 and continues to w-1,0, w-1,1
SomeRandomBloke 3:dfffbd9f8ac6 64 // and on to 0,1, 0,2 and on to w-1,2 and so on. Snaking back and forth till the end.
SomeRandomBloke 3:dfffbd9f8ac6 65 // other function calls with provide access to pixels via an x,y coordinate system
SomeRandomBloke 3:dfffbd9f8ac6 66 /*Adafruit_WS2801::Adafruit_WS2801(uint16_t w, uint16_t h, uint8_t order)
SomeRandomBloke 3:dfffbd9f8ac6 67 {
SomeRandomBloke 3:dfffbd9f8ac6 68 rgb_order = order;
SomeRandomBloke 3:dfffbd9f8ac6 69 alloc(w * h);
SomeRandomBloke 3:dfffbd9f8ac6 70 width = w;
SomeRandomBloke 3:dfffbd9f8ac6 71 height = h;
SomeRandomBloke 3:dfffbd9f8ac6 72 hardwareSPI = true;
SomeRandomBloke 3:dfffbd9f8ac6 73 // updatePins(dpin, cpin);
SomeRandomBloke 3:dfffbd9f8ac6 74 }
SomeRandomBloke 3:dfffbd9f8ac6 75 */
SomeRandomBloke 3:dfffbd9f8ac6 76
SomeRandomBloke 3:dfffbd9f8ac6 77
SomeRandomBloke 3:dfffbd9f8ac6 78
SomeRandomBloke 0:582e1b9c1cc1 79 // via Michael Vogt/neophob: empty constructor is used when strand length
SomeRandomBloke 0:582e1b9c1cc1 80 // isn't known at compile-time; situations where program config might be
SomeRandomBloke 0:582e1b9c1cc1 81 // read from internal flash memory or an SD card, or arrive via serial
SomeRandomBloke 0:582e1b9c1cc1 82 // command. If using this constructor, MUST follow up with updateLength()
SomeRandomBloke 0:582e1b9c1cc1 83 // and updatePins() to establish the strand length and output pins!
SomeRandomBloke 0:582e1b9c1cc1 84 // Also, updateOrder() to change RGB vs GRB order (RGB is default).
SomeRandomBloke 1:6ff477690983 85 //Adafruit_WS2801::Adafruit_WS2801(void) : clkpin(PTD4), datapin(PTA12)
SomeRandomBloke 1:6ff477690983 86 //{
SomeRandomBloke 1:6ff477690983 87 // begun = false;
SomeRandomBloke 1:6ff477690983 88 // numLEDs = 0;
SomeRandomBloke 1:6ff477690983 89 // pixels = NULL;
SomeRandomBloke 1:6ff477690983 90 // rgb_order = WS2801_RGB;
SomeRandomBloke 1:6ff477690983 91 // updatePins(); // Must assume hardware SPI until pins are set
SomeRandomBloke 1:6ff477690983 92 //}
SomeRandomBloke 0:582e1b9c1cc1 93
SomeRandomBloke 0:582e1b9c1cc1 94 // Release memory (as needed):
SomeRandomBloke 0:582e1b9c1cc1 95 Adafruit_WS2801::~Adafruit_WS2801(void)
SomeRandomBloke 0:582e1b9c1cc1 96 {
SomeRandomBloke 0:582e1b9c1cc1 97 if (pixels != NULL) {
SomeRandomBloke 0:582e1b9c1cc1 98 free(pixels);
SomeRandomBloke 0:582e1b9c1cc1 99 }
SomeRandomBloke 0:582e1b9c1cc1 100 }
SomeRandomBloke 0:582e1b9c1cc1 101
SomeRandomBloke 0:582e1b9c1cc1 102 // Activate hard/soft SPI as appropriate:
SomeRandomBloke 0:582e1b9c1cc1 103 void Adafruit_WS2801::begin(void)
SomeRandomBloke 0:582e1b9c1cc1 104 {
SomeRandomBloke 2:2fdaa13896a4 105 if( hardwareSPI ) {
SomeRandomBloke 2:2fdaa13896a4 106 // Setup the spi for 8 bit data, high steady state clock,
SomeRandomBloke 2:2fdaa13896a4 107 // second edge capture, with a 1MHz clock rate
SomeRandomBloke 2:2fdaa13896a4 108 spi.format(8,0);
SomeRandomBloke 2:2fdaa13896a4 109 spi.frequency(1000000);
SomeRandomBloke 2:2fdaa13896a4 110 } else {
SomeRandomBloke 2:2fdaa13896a4 111 datapin = 0;
SomeRandomBloke 2:2fdaa13896a4 112 clkpin = 0;
SomeRandomBloke 2:2fdaa13896a4 113 }
SomeRandomBloke 0:582e1b9c1cc1 114 begun = true;
SomeRandomBloke 0:582e1b9c1cc1 115 }
SomeRandomBloke 0:582e1b9c1cc1 116
SomeRandomBloke 0:582e1b9c1cc1 117 // Change pin assignments post-constructor, switching to hardware SPI:
SomeRandomBloke 0:582e1b9c1cc1 118 void Adafruit_WS2801::updatePins(void)
SomeRandomBloke 0:582e1b9c1cc1 119 {
SomeRandomBloke 0:582e1b9c1cc1 120 hardwareSPI = true;
SomeRandomBloke 0:582e1b9c1cc1 121 datapin = 0;
SomeRandomBloke 0:582e1b9c1cc1 122 clkpin = 0;
SomeRandomBloke 0:582e1b9c1cc1 123 }
SomeRandomBloke 2:2fdaa13896a4 124
SomeRandomBloke 0:582e1b9c1cc1 125
SomeRandomBloke 0:582e1b9c1cc1 126 // Change pin assignments post-constructor, using arbitrary pins:
SomeRandomBloke 3:dfffbd9f8ac6 127 void Adafruit_WS2801::updatePins(PinName dpin, PinName cpin)
SomeRandomBloke 3:dfffbd9f8ac6 128 {
SomeRandomBloke 0:582e1b9c1cc1 129 // Note: any prior clock/data pin directions are left as-is and are
SomeRandomBloke 0:582e1b9c1cc1 130 // NOT restored as inputs!
SomeRandomBloke 0:582e1b9c1cc1 131
SomeRandomBloke 3:dfffbd9f8ac6 132 datapin = DigitalOut(dpin);
SomeRandomBloke 3:dfffbd9f8ac6 133 clkpin = DigitalOut(cpin);
SomeRandomBloke 3:dfffbd9f8ac6 134 }
SomeRandomBloke 0:582e1b9c1cc1 135
SomeRandomBloke 3:dfffbd9f8ac6 136 // Return the number of LEDs
SomeRandomBloke 0:582e1b9c1cc1 137 uint16_t Adafruit_WS2801::numPixels(void)
SomeRandomBloke 0:582e1b9c1cc1 138 {
SomeRandomBloke 0:582e1b9c1cc1 139 return numLEDs;
SomeRandomBloke 0:582e1b9c1cc1 140 }
SomeRandomBloke 0:582e1b9c1cc1 141
SomeRandomBloke 0:582e1b9c1cc1 142 // Change strand length (see notes with empty constructor, above):
SomeRandomBloke 0:582e1b9c1cc1 143 void Adafruit_WS2801::updateLength(uint16_t n)
SomeRandomBloke 0:582e1b9c1cc1 144 {
SomeRandomBloke 0:582e1b9c1cc1 145 if(pixels != NULL) free(pixels); // Free existing data (if any)
SomeRandomBloke 0:582e1b9c1cc1 146 // Allocate new data -- note: ALL PIXELS ARE CLEARED
SomeRandomBloke 0:582e1b9c1cc1 147 numLEDs = ((pixels = (uint8_t *)calloc(n, 3)) != NULL) ? n : 0;
SomeRandomBloke 0:582e1b9c1cc1 148 // 'begun' state does not change -- pins retain prior modes
SomeRandomBloke 0:582e1b9c1cc1 149 }
SomeRandomBloke 0:582e1b9c1cc1 150
SomeRandomBloke 0:582e1b9c1cc1 151 // Change RGB data order (see notes with empty constructor, above):
SomeRandomBloke 0:582e1b9c1cc1 152 void Adafruit_WS2801::updateOrder(uint8_t order)
SomeRandomBloke 0:582e1b9c1cc1 153 {
SomeRandomBloke 0:582e1b9c1cc1 154 rgb_order = order;
SomeRandomBloke 0:582e1b9c1cc1 155 // Existing LED data, if any, is NOT reformatted to new data order.
SomeRandomBloke 0:582e1b9c1cc1 156 // Calling function should clear or fill pixel data anew.
SomeRandomBloke 0:582e1b9c1cc1 157 }
SomeRandomBloke 0:582e1b9c1cc1 158
SomeRandomBloke 0:582e1b9c1cc1 159 void Adafruit_WS2801::show(void)
SomeRandomBloke 0:582e1b9c1cc1 160 {
SomeRandomBloke 0:582e1b9c1cc1 161 uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
SomeRandomBloke 2:2fdaa13896a4 162
SomeRandomBloke 2:2fdaa13896a4 163 if( hardwareSPI ) {
SomeRandomBloke 2:2fdaa13896a4 164 for(i=0; i<nl3; i++ ) {
SomeRandomBloke 2:2fdaa13896a4 165 spi.write( pixels[i]);
SomeRandomBloke 2:2fdaa13896a4 166 }
SomeRandomBloke 4:987c91c45188 167 wait_ms(1); // Needed otherwise sometimes doesnt display
SomeRandomBloke 2:2fdaa13896a4 168 } else {
SomeRandomBloke 2:2fdaa13896a4 169 uint8_t bit;
SomeRandomBloke 0:582e1b9c1cc1 170
SomeRandomBloke 2:2fdaa13896a4 171 // Write 24 bits per pixel:
SomeRandomBloke 2:2fdaa13896a4 172 for(i=0; i<nl3; i++ ) {
SomeRandomBloke 2:2fdaa13896a4 173 for(bit=0x80; bit; bit >>= 1) {
SomeRandomBloke 2:2fdaa13896a4 174 clkpin = 0;
SomeRandomBloke 2:2fdaa13896a4 175 datapin = (pixels[i] & bit) ? 1 : 0;
SomeRandomBloke 2:2fdaa13896a4 176 clkpin = 1;
SomeRandomBloke 2:2fdaa13896a4 177 wait_us(100);
SomeRandomBloke 2:2fdaa13896a4 178 }
SomeRandomBloke 0:582e1b9c1cc1 179 }
SomeRandomBloke 2:2fdaa13896a4 180 datapin = 0;
SomeRandomBloke 0:582e1b9c1cc1 181
SomeRandomBloke 2:2fdaa13896a4 182 clkpin = 0;
SomeRandomBloke 2:2fdaa13896a4 183 wait_ms(1); // Data is latched by holding clock pin low for 1 millisecond
SomeRandomBloke 2:2fdaa13896a4 184 clkpin = 1;
SomeRandomBloke 2:2fdaa13896a4 185 }
SomeRandomBloke 0:582e1b9c1cc1 186 }
SomeRandomBloke 0:582e1b9c1cc1 187
SomeRandomBloke 0:582e1b9c1cc1 188 // Set pixel color from separate 8-bit R, G, B components:
SomeRandomBloke 0:582e1b9c1cc1 189 void Adafruit_WS2801::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
SomeRandomBloke 0:582e1b9c1cc1 190 {
SomeRandomBloke 0:582e1b9c1cc1 191 if(n < numLEDs) { // Arrays are 0-indexed, thus NOT '<='
SomeRandomBloke 0:582e1b9c1cc1 192 uint8_t *p = &pixels[n * 3];
SomeRandomBloke 0:582e1b9c1cc1 193 // See notes later regarding color order
SomeRandomBloke 0:582e1b9c1cc1 194 if(rgb_order == WS2801_RGB) {
SomeRandomBloke 0:582e1b9c1cc1 195 *p++ = r;
SomeRandomBloke 0:582e1b9c1cc1 196 *p++ = g;
SomeRandomBloke 0:582e1b9c1cc1 197 } else {
SomeRandomBloke 0:582e1b9c1cc1 198 *p++ = g;
SomeRandomBloke 0:582e1b9c1cc1 199 *p++ = r;
SomeRandomBloke 0:582e1b9c1cc1 200 }
SomeRandomBloke 0:582e1b9c1cc1 201 *p++ = b;
SomeRandomBloke 0:582e1b9c1cc1 202 }
SomeRandomBloke 0:582e1b9c1cc1 203 }
SomeRandomBloke 0:582e1b9c1cc1 204
SomeRandomBloke 0:582e1b9c1cc1 205 // Set pixel color from separate 8-bit R, G, B components using x,y coordinate system:
SomeRandomBloke 3:dfffbd9f8ac6 206 void Adafruit_WS2801::setPixelColor(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b)
SomeRandomBloke 0:582e1b9c1cc1 207 {
SomeRandomBloke 3:dfffbd9f8ac6 208 if( x < 0 || x >= width || y < 0 || y >= height )
SomeRandomBloke 3:dfffbd9f8ac6 209 return; // Dont try to update a pixel that doesnt exist
SomeRandomBloke 3:dfffbd9f8ac6 210
SomeRandomBloke 0:582e1b9c1cc1 211 bool evenRow = ((y % 2) == 0);
SomeRandomBloke 0:582e1b9c1cc1 212 // calculate x offset first
SomeRandomBloke 0:582e1b9c1cc1 213 uint16_t offset = x % width;
SomeRandomBloke 3:dfffbd9f8ac6 214
SomeRandomBloke 0:582e1b9c1cc1 215 if (!evenRow) {
SomeRandomBloke 0:582e1b9c1cc1 216 offset = (width-1) - offset;
SomeRandomBloke 0:582e1b9c1cc1 217 }
SomeRandomBloke 0:582e1b9c1cc1 218 // add y offset
SomeRandomBloke 0:582e1b9c1cc1 219 offset += y * width;
SomeRandomBloke 0:582e1b9c1cc1 220 setPixelColor(offset, r, g, b);
SomeRandomBloke 0:582e1b9c1cc1 221 }
SomeRandomBloke 0:582e1b9c1cc1 222
SomeRandomBloke 0:582e1b9c1cc1 223 // Set pixel color from 'packed' 32-bit RGB value:
SomeRandomBloke 0:582e1b9c1cc1 224 void Adafruit_WS2801::setPixelColor(uint16_t n, uint32_t c)
SomeRandomBloke 0:582e1b9c1cc1 225 {
SomeRandomBloke 3:dfffbd9f8ac6 226 if( n < numLEDs) { // Arrays are 0-indexed, thus NOT '<='
SomeRandomBloke 0:582e1b9c1cc1 227 uint8_t *p = &pixels[n * 3];
SomeRandomBloke 0:582e1b9c1cc1 228 // To keep the show() loop as simple & fast as possible, the
SomeRandomBloke 0:582e1b9c1cc1 229 // internal color representation is native to different pixel
SomeRandomBloke 0:582e1b9c1cc1 230 // types. For compatibility with existing code, 'packed' RGB
SomeRandomBloke 0:582e1b9c1cc1 231 // values passed in or out are always 0xRRGGBB order.
SomeRandomBloke 0:582e1b9c1cc1 232 if(rgb_order == WS2801_RGB) {
SomeRandomBloke 0:582e1b9c1cc1 233 *p++ = c >> 16; // Red
SomeRandomBloke 0:582e1b9c1cc1 234 *p++ = c >> 8; // Green
SomeRandomBloke 0:582e1b9c1cc1 235 } else {
SomeRandomBloke 0:582e1b9c1cc1 236 *p++ = c >> 8; // Green
SomeRandomBloke 0:582e1b9c1cc1 237 *p++ = c >> 16; // Red
SomeRandomBloke 0:582e1b9c1cc1 238 }
SomeRandomBloke 0:582e1b9c1cc1 239 *p++ = c; // Blue
SomeRandomBloke 0:582e1b9c1cc1 240 }
SomeRandomBloke 0:582e1b9c1cc1 241 }
SomeRandomBloke 0:582e1b9c1cc1 242
SomeRandomBloke 0:582e1b9c1cc1 243 // Set pixel color from 'packed' 32-bit RGB value using x,y coordinate system:
SomeRandomBloke 3:dfffbd9f8ac6 244 void Adafruit_WS2801::setPixelColor(int16_t x, int16_t y, uint32_t c)
SomeRandomBloke 0:582e1b9c1cc1 245 {
SomeRandomBloke 3:dfffbd9f8ac6 246 if( x < 0 || x >= width || y < 0 || y >= height )
SomeRandomBloke 3:dfffbd9f8ac6 247 return; // Dont try to update a pixel that doesnt exist
SomeRandomBloke 3:dfffbd9f8ac6 248
SomeRandomBloke 0:582e1b9c1cc1 249 bool evenRow = ((y % 2) == 0);
SomeRandomBloke 0:582e1b9c1cc1 250 // calculate x offset first
SomeRandomBloke 0:582e1b9c1cc1 251 uint16_t offset = x % width;
SomeRandomBloke 0:582e1b9c1cc1 252 if (!evenRow) {
SomeRandomBloke 0:582e1b9c1cc1 253 offset = (width-1) - offset;
SomeRandomBloke 0:582e1b9c1cc1 254 }
SomeRandomBloke 0:582e1b9c1cc1 255 // add y offset
SomeRandomBloke 0:582e1b9c1cc1 256 offset += y * width;
SomeRandomBloke 0:582e1b9c1cc1 257 setPixelColor(offset, c);
SomeRandomBloke 0:582e1b9c1cc1 258 }
SomeRandomBloke 0:582e1b9c1cc1 259
SomeRandomBloke 0:582e1b9c1cc1 260 // Query color from previously-set pixel (returns packed 32-bit RGB value)
SomeRandomBloke 0:582e1b9c1cc1 261 uint32_t Adafruit_WS2801::getPixelColor(uint16_t n)
SomeRandomBloke 0:582e1b9c1cc1 262 {
SomeRandomBloke 0:582e1b9c1cc1 263 if(n < numLEDs) {
SomeRandomBloke 0:582e1b9c1cc1 264 uint16_t ofs = n * 3;
SomeRandomBloke 0:582e1b9c1cc1 265 // To keep the show() loop as simple & fast as possible, the
SomeRandomBloke 0:582e1b9c1cc1 266 // internal color representation is native to different pixel
SomeRandomBloke 0:582e1b9c1cc1 267 // types. For compatibility with existing code, 'packed' RGB
SomeRandomBloke 0:582e1b9c1cc1 268 // values passed in or out are always 0xRRGGBB order.
SomeRandomBloke 0:582e1b9c1cc1 269 return (rgb_order == WS2801_RGB) ?
SomeRandomBloke 0:582e1b9c1cc1 270 ((uint32_t)pixels[ofs] << 16) | ((uint16_t) pixels[ofs + 1] << 8) | pixels[ofs + 2] :
SomeRandomBloke 0:582e1b9c1cc1 271 (pixels[ofs] << 8) | ((uint32_t)pixels[ofs + 1] << 16) | pixels[ofs + 2];
SomeRandomBloke 0:582e1b9c1cc1 272 }
SomeRandomBloke 0:582e1b9c1cc1 273
SomeRandomBloke 0:582e1b9c1cc1 274 return 0; // Pixel # is out of bounds
SomeRandomBloke 0:582e1b9c1cc1 275 }
SomeRandomBloke 3:dfffbd9f8ac6 276
SomeRandomBloke 3:dfffbd9f8ac6 277 // bresenham's algorithm - thx wikpedia
SomeRandomBloke 3:dfffbd9f8ac6 278 void Adafruit_WS2801::drawLine(int16_t x0, int16_t y0,
SomeRandomBloke 3:dfffbd9f8ac6 279 int16_t x1, int16_t y1,
SomeRandomBloke 3:dfffbd9f8ac6 280 uint32_t color) {
SomeRandomBloke 3:dfffbd9f8ac6 281 int16_t steep = abs(y1 - y0) > abs(x1 - x0);
SomeRandomBloke 3:dfffbd9f8ac6 282 if (steep) {
SomeRandomBloke 3:dfffbd9f8ac6 283 ws_swap(x0, y0);
SomeRandomBloke 3:dfffbd9f8ac6 284 ws_swap(x1, y1);
SomeRandomBloke 3:dfffbd9f8ac6 285 }
SomeRandomBloke 3:dfffbd9f8ac6 286
SomeRandomBloke 3:dfffbd9f8ac6 287 if (x0 > x1) {
SomeRandomBloke 3:dfffbd9f8ac6 288 ws_swap(x0, x1);
SomeRandomBloke 3:dfffbd9f8ac6 289 ws_swap(y0, y1);
SomeRandomBloke 3:dfffbd9f8ac6 290 }
SomeRandomBloke 3:dfffbd9f8ac6 291
SomeRandomBloke 3:dfffbd9f8ac6 292 int16_t dx, dy;
SomeRandomBloke 3:dfffbd9f8ac6 293 dx = x1 - x0;
SomeRandomBloke 3:dfffbd9f8ac6 294 dy = abs(y1 - y0);
SomeRandomBloke 3:dfffbd9f8ac6 295
SomeRandomBloke 3:dfffbd9f8ac6 296 int16_t err = dx / 2;
SomeRandomBloke 3:dfffbd9f8ac6 297 int16_t ystep;
SomeRandomBloke 3:dfffbd9f8ac6 298
SomeRandomBloke 3:dfffbd9f8ac6 299 if (y0 < y1) {
SomeRandomBloke 3:dfffbd9f8ac6 300 ystep = 1;
SomeRandomBloke 3:dfffbd9f8ac6 301 } else {
SomeRandomBloke 3:dfffbd9f8ac6 302 ystep = -1;
SomeRandomBloke 3:dfffbd9f8ac6 303 }
SomeRandomBloke 3:dfffbd9f8ac6 304
SomeRandomBloke 3:dfffbd9f8ac6 305 for (; x0<=x1; x0++) {
SomeRandomBloke 3:dfffbd9f8ac6 306 if (steep) {
SomeRandomBloke 3:dfffbd9f8ac6 307 setPixelColor(y0, x0, color);
SomeRandomBloke 3:dfffbd9f8ac6 308 } else {
SomeRandomBloke 3:dfffbd9f8ac6 309 setPixelColor(x0, y0, color);
SomeRandomBloke 3:dfffbd9f8ac6 310 }
SomeRandomBloke 3:dfffbd9f8ac6 311 err -= dy;
SomeRandomBloke 3:dfffbd9f8ac6 312 if (err < 0) {
SomeRandomBloke 3:dfffbd9f8ac6 313 y0 += ystep;
SomeRandomBloke 3:dfffbd9f8ac6 314 err += dx;
SomeRandomBloke 3:dfffbd9f8ac6 315 }
SomeRandomBloke 3:dfffbd9f8ac6 316 }
SomeRandomBloke 3:dfffbd9f8ac6 317 }
SomeRandomBloke 3:dfffbd9f8ac6 318
SomeRandomBloke 3:dfffbd9f8ac6 319 void Adafruit_WS2801::drawFastVLine(int16_t x, int16_t y,
SomeRandomBloke 3:dfffbd9f8ac6 320 int16_t h, uint32_t color) {
SomeRandomBloke 3:dfffbd9f8ac6 321 // stupidest version - update in subclasses if desired!
SomeRandomBloke 3:dfffbd9f8ac6 322 drawLine(x, y, x, y+h-1, color);
SomeRandomBloke 3:dfffbd9f8ac6 323 }
SomeRandomBloke 3:dfffbd9f8ac6 324
SomeRandomBloke 3:dfffbd9f8ac6 325
SomeRandomBloke 3:dfffbd9f8ac6 326 void Adafruit_WS2801::drawFastHLine(int16_t x, int16_t y,
SomeRandomBloke 3:dfffbd9f8ac6 327 int16_t w, uint32_t color) {
SomeRandomBloke 3:dfffbd9f8ac6 328 // stupidest version - update in subclasses if desired!
SomeRandomBloke 3:dfffbd9f8ac6 329 drawLine(x, y, x+w-1, y, color);
SomeRandomBloke 3:dfffbd9f8ac6 330 }
SomeRandomBloke 3:dfffbd9f8ac6 331
SomeRandomBloke 3:dfffbd9f8ac6 332
SomeRandomBloke 3:dfffbd9f8ac6 333 // draw a rectangle
SomeRandomBloke 3:dfffbd9f8ac6 334 void Adafruit_WS2801::drawRect(int16_t x, int16_t y,
SomeRandomBloke 3:dfffbd9f8ac6 335 int16_t w, int16_t h, uint32_t color) {
SomeRandomBloke 3:dfffbd9f8ac6 336 drawFastHLine(x, y, w, color);
SomeRandomBloke 3:dfffbd9f8ac6 337 drawFastHLine(x, y+h-1, w, color);
SomeRandomBloke 3:dfffbd9f8ac6 338 drawFastVLine(x, y, h, color);
SomeRandomBloke 3:dfffbd9f8ac6 339 drawFastVLine(x+w-1, y, h, color);
SomeRandomBloke 3:dfffbd9f8ac6 340 }
SomeRandomBloke 3:dfffbd9f8ac6 341
SomeRandomBloke 3:dfffbd9f8ac6 342 // draw a circle outline
SomeRandomBloke 3:dfffbd9f8ac6 343 void Adafruit_WS2801::drawCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color) {
SomeRandomBloke 3:dfffbd9f8ac6 344 int16_t f = 1 - r;
SomeRandomBloke 3:dfffbd9f8ac6 345 int16_t ddF_x = 1;
SomeRandomBloke 3:dfffbd9f8ac6 346 int16_t ddF_y = -2 * r;
SomeRandomBloke 3:dfffbd9f8ac6 347 int16_t x = 0;
SomeRandomBloke 3:dfffbd9f8ac6 348 int16_t y = r;
SomeRandomBloke 3:dfffbd9f8ac6 349
SomeRandomBloke 3:dfffbd9f8ac6 350 setPixelColor(x0, y0+r, color);
SomeRandomBloke 3:dfffbd9f8ac6 351 setPixelColor(x0, y0-r, color);
SomeRandomBloke 3:dfffbd9f8ac6 352 setPixelColor(x0+r, y0, color);
SomeRandomBloke 3:dfffbd9f8ac6 353 setPixelColor(x0-r, y0, color);
SomeRandomBloke 3:dfffbd9f8ac6 354
SomeRandomBloke 3:dfffbd9f8ac6 355 while (x<y) {
SomeRandomBloke 3:dfffbd9f8ac6 356 if (f >= 0) {
SomeRandomBloke 3:dfffbd9f8ac6 357 y--;
SomeRandomBloke 3:dfffbd9f8ac6 358 ddF_y += 2;
SomeRandomBloke 3:dfffbd9f8ac6 359 f += ddF_y;
SomeRandomBloke 3:dfffbd9f8ac6 360 }
SomeRandomBloke 3:dfffbd9f8ac6 361 x++;
SomeRandomBloke 3:dfffbd9f8ac6 362 ddF_x += 2;
SomeRandomBloke 3:dfffbd9f8ac6 363 f += ddF_x;
SomeRandomBloke 3:dfffbd9f8ac6 364
SomeRandomBloke 3:dfffbd9f8ac6 365 setPixelColor(x0 + x, y0 + y, color);
SomeRandomBloke 3:dfffbd9f8ac6 366 setPixelColor(x0 - x, y0 + y, color);
SomeRandomBloke 3:dfffbd9f8ac6 367 setPixelColor(x0 + x, y0 - y, color);
SomeRandomBloke 3:dfffbd9f8ac6 368 setPixelColor(x0 - x, y0 - y, color);
SomeRandomBloke 3:dfffbd9f8ac6 369 setPixelColor(x0 + y, y0 + x, color);
SomeRandomBloke 3:dfffbd9f8ac6 370 setPixelColor(x0 - y, y0 + x, color);
SomeRandomBloke 3:dfffbd9f8ac6 371 setPixelColor(x0 + y, y0 - x, color);
SomeRandomBloke 3:dfffbd9f8ac6 372 setPixelColor(x0 - y, y0 - x, color);
SomeRandomBloke 3:dfffbd9f8ac6 373
SomeRandomBloke 3:dfffbd9f8ac6 374 }
SomeRandomBloke 3:dfffbd9f8ac6 375 }
SomeRandomBloke 3:dfffbd9f8ac6 376 /*
SomeRandomBloke 3:dfffbd9f8ac6 377 void Adafruit_WS2801::fillCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color) {
SomeRandomBloke 3:dfffbd9f8ac6 378 drawFastVLine(x0, y0-r, 2*r+1, color);
SomeRandomBloke 3:dfffbd9f8ac6 379 fillCircleHelper(x0, y0, r, 3, 0, color);
SomeRandomBloke 3:dfffbd9f8ac6 380 }
SomeRandomBloke 3:dfffbd9f8ac6 381
SomeRandomBloke 3:dfffbd9f8ac6 382 // used to do circles and roundrects!
SomeRandomBloke 3:dfffbd9f8ac6 383 void Adafruit_WS2801::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
SomeRandomBloke 3:dfffbd9f8ac6 384 uint8_t cornername, int16_t delta, uint32_t color) {
SomeRandomBloke 3:dfffbd9f8ac6 385
SomeRandomBloke 3:dfffbd9f8ac6 386 int16_t f = 1 - r;
SomeRandomBloke 3:dfffbd9f8ac6 387 int16_t ddF_x = 1;
SomeRandomBloke 3:dfffbd9f8ac6 388 int16_t ddF_y = -2 * r;
SomeRandomBloke 3:dfffbd9f8ac6 389 int16_t x = 0;
SomeRandomBloke 3:dfffbd9f8ac6 390 int16_t y = r;
SomeRandomBloke 3:dfffbd9f8ac6 391
SomeRandomBloke 3:dfffbd9f8ac6 392 while (x<y) {
SomeRandomBloke 3:dfffbd9f8ac6 393 if (f >= 0) {
SomeRandomBloke 3:dfffbd9f8ac6 394 y--;
SomeRandomBloke 3:dfffbd9f8ac6 395 ddF_y += 2;
SomeRandomBloke 3:dfffbd9f8ac6 396 f += ddF_y;
SomeRandomBloke 3:dfffbd9f8ac6 397 }
SomeRandomBloke 3:dfffbd9f8ac6 398 x++;
SomeRandomBloke 3:dfffbd9f8ac6 399 ddF_x += 2;
SomeRandomBloke 3:dfffbd9f8ac6 400 f += ddF_x;
SomeRandomBloke 3:dfffbd9f8ac6 401
SomeRandomBloke 3:dfffbd9f8ac6 402 if (cornername & 0x1) {
SomeRandomBloke 3:dfffbd9f8ac6 403 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
SomeRandomBloke 3:dfffbd9f8ac6 404 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
SomeRandomBloke 3:dfffbd9f8ac6 405 }
SomeRandomBloke 3:dfffbd9f8ac6 406 if (cornername & 0x2) {
SomeRandomBloke 3:dfffbd9f8ac6 407 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
SomeRandomBloke 3:dfffbd9f8ac6 408 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
SomeRandomBloke 3:dfffbd9f8ac6 409 }
SomeRandomBloke 3:dfffbd9f8ac6 410 }
SomeRandomBloke 3:dfffbd9f8ac6 411 }
SomeRandomBloke 3:dfffbd9f8ac6 412 */