This is a fork of Adafruit_WS2801 found http://developer.mbed.org/users/SomeRandomBloke/code/Adafruit_WS2801/ It was the work of SomeRandomBloke, and I changed some baked in settings to work with the STM32F401RE.
Fork of Adafruit_WS2801 by
Adafruit_WS2801.cpp
00001 #include "mbed.h" 00002 #include "Adafruit_WS2801.h" 00003 00004 00005 // Example to control WS2801-based RGB LED Modules in a strand or strip 00006 // Written by Adafruit - MIT license 00007 /*****************************************************************************/ 00008 00009 SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK); // mosi, miso, sclk 00010 00011 // Constructor for use with hardware SPI (specific clock/data pins): 00012 /*Adafruit_WS2801::Adafruit_WS2801(uint16_t n, uint8_t order): clkpin(PTD4), datapin(PTA12) 00013 { 00014 rgb_order = order; 00015 alloc(n); 00016 updatePins(); 00017 }*/ 00018 00019 // Constructor for use with arbitrary clock/data pins: 00020 Adafruit_WS2801::Adafruit_WS2801(int16_t n, PinName dpin, PinName cpin, uint8_t order) 00021 : clkpin(cpin), datapin(dpin) 00022 { 00023 rgb_order = order; 00024 alloc(n); 00025 width = 1; 00026 height = n; 00027 hardwareSPI = false; 00028 // updatePins(dpin, cpin); 00029 } 00030 00031 // Constructor for use with a matrix configuration, specify w, h for size of matrix 00032 // assumes configuration where string starts at coordinate 0,0 and continues to w-1,0, w-1,1 00033 // and on to 0,1, 0,2 and on to w-1,2 and so on. Snaking back and forth till the end. 00034 // other function calls with provide access to pixels via an x,y coordinate system 00035 Adafruit_WS2801::Adafruit_WS2801(int16_t w, int16_t h, PinName dpin, PinName cpin, uint8_t order) 00036 : clkpin(cpin), datapin(dpin) 00037 { 00038 rgb_order = order; 00039 alloc(w * h); 00040 width = w; 00041 height = h; 00042 hardwareSPI = false; 00043 // updatePins(dpin, cpin); 00044 } 00045 00046 // Allocate 3 bytes per pixel, init to RGB 'off' state: 00047 void Adafruit_WS2801::alloc(uint16_t n) 00048 { 00049 begun = false; 00050 numLEDs = ((pixels = (uint8_t *)calloc(n, 3)) != NULL) ? n : 0; 00051 hardwareSPI = true; 00052 00053 // for(int bits = 0; bits <= numLEDs*24; bits++) { 00054 // spi.write(0x00); 00055 // clkpin = 0; 00056 // datapin = 0; 00057 // clkpin = 1; 00058 // } 00059 // clkpin = 0; 00060 } 00061 00062 // Constructor for use with a matrix configuration, specify w, h for size of matrix 00063 // assumes configuration where string starts at coordinate 0,0 and continues to w-1,0, w-1,1 00064 // and on to 0,1, 0,2 and on to w-1,2 and so on. Snaking back and forth till the end. 00065 // other function calls with provide access to pixels via an x,y coordinate system 00066 /*Adafruit_WS2801::Adafruit_WS2801(uint16_t w, uint16_t h, uint8_t order) 00067 { 00068 rgb_order = order; 00069 alloc(w * h); 00070 width = w; 00071 height = h; 00072 hardwareSPI = true; 00073 // updatePins(dpin, cpin); 00074 } 00075 */ 00076 00077 00078 00079 // via Michael Vogt/neophob: empty constructor is used when strand length 00080 // isn't known at compile-time; situations where program config might be 00081 // read from internal flash memory or an SD card, or arrive via serial 00082 // command. If using this constructor, MUST follow up with updateLength() 00083 // and updatePins() to establish the strand length and output pins! 00084 // Also, updateOrder() to change RGB vs GRB order (RGB is default). 00085 //Adafruit_WS2801::Adafruit_WS2801(void) : clkpin(PTD4), datapin(PTA12) 00086 //{ 00087 // begun = false; 00088 // numLEDs = 0; 00089 // pixels = NULL; 00090 // rgb_order = WS2801_RGB; 00091 // updatePins(); // Must assume hardware SPI until pins are set 00092 //} 00093 00094 // Release memory (as needed): 00095 Adafruit_WS2801::~Adafruit_WS2801(void) 00096 { 00097 if (pixels != NULL) { 00098 free(pixels); 00099 } 00100 } 00101 00102 // Activate hard/soft SPI as appropriate: 00103 void Adafruit_WS2801::begin(void) 00104 { 00105 if( hardwareSPI ) { 00106 // Setup the spi for 8 bit data, high steady state clock, 00107 // second edge capture, with a 1MHz clock rate 00108 spi.format(8,0); 00109 spi.frequency(1000000); 00110 } else { 00111 datapin = 0; 00112 clkpin = 0; 00113 } 00114 begun = true; 00115 } 00116 00117 // Change pin assignments post-constructor, switching to hardware SPI: 00118 void Adafruit_WS2801::updatePins(void) 00119 { 00120 hardwareSPI = true; 00121 datapin = 0; 00122 clkpin = 0; 00123 } 00124 00125 00126 // Change pin assignments post-constructor, using arbitrary pins: 00127 void Adafruit_WS2801::updatePins(PinName dpin, PinName cpin) 00128 { 00129 // Note: any prior clock/data pin directions are left as-is and are 00130 // NOT restored as inputs! 00131 00132 datapin = DigitalOut(dpin); 00133 clkpin = DigitalOut(cpin); 00134 } 00135 00136 // Return the number of LEDs 00137 uint16_t Adafruit_WS2801::numPixels(void) 00138 { 00139 return numLEDs; 00140 } 00141 00142 // Change strand length (see notes with empty constructor, above): 00143 void Adafruit_WS2801::updateLength(uint16_t n) 00144 { 00145 if(pixels != NULL) free(pixels); // Free existing data (if any) 00146 // Allocate new data -- note: ALL PIXELS ARE CLEARED 00147 numLEDs = ((pixels = (uint8_t *)calloc(n, 3)) != NULL) ? n : 0; 00148 // 'begun' state does not change -- pins retain prior modes 00149 } 00150 00151 // Change RGB data order (see notes with empty constructor, above): 00152 void Adafruit_WS2801::updateOrder(uint8_t order) 00153 { 00154 rgb_order = order; 00155 // Existing LED data, if any, is NOT reformatted to new data order. 00156 // Calling function should clear or fill pixel data anew. 00157 } 00158 00159 void Adafruit_WS2801::show(void) 00160 { 00161 uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED 00162 00163 if( hardwareSPI ) { 00164 for(i=0; i<nl3; i++ ) { 00165 spi.write( pixels[i]); 00166 } 00167 wait_ms(1); // Needed otherwise sometimes doesnt display 00168 } else { 00169 uint8_t bit; 00170 00171 // Write 24 bits per pixel: 00172 for(i=0; i<nl3; i++ ) { 00173 for(bit=0x80; bit; bit >>= 1) { 00174 clkpin = 0; 00175 datapin = (pixels[i] & bit) ? 1 : 0; 00176 clkpin = 1; 00177 wait_us(100); 00178 } 00179 } 00180 datapin = 0; 00181 00182 clkpin = 0; 00183 wait_ms(1); // Data is latched by holding clock pin low for 1 millisecond 00184 clkpin = 1; 00185 } 00186 } 00187 00188 // Set pixel color from separate 8-bit R, G, B components: 00189 void Adafruit_WS2801::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) 00190 { 00191 if(n < numLEDs) { // Arrays are 0-indexed, thus NOT '<=' 00192 uint8_t *p = &pixels[n * 3]; 00193 // See notes later regarding color order 00194 if(rgb_order == WS2801_RGB) { 00195 *p++ = r; 00196 *p++ = g; 00197 } else { 00198 *p++ = g; 00199 *p++ = r; 00200 } 00201 *p++ = b; 00202 } 00203 } 00204 00205 // Set pixel color from separate 8-bit R, G, B components using x,y coordinate system: 00206 void Adafruit_WS2801::setPixelColor(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b) 00207 { 00208 if( x < 0 || x >= width || y < 0 || y >= height ) 00209 return; // Dont try to update a pixel that doesnt exist 00210 00211 bool evenRow = ((y % 2) == 0); 00212 // calculate x offset first 00213 uint16_t offset = x % width; 00214 00215 if (!evenRow) { 00216 offset = (width-1) - offset; 00217 } 00218 // add y offset 00219 offset += y * width; 00220 setPixelColor(offset, r, g, b); 00221 } 00222 00223 // Set pixel color from 'packed' 32-bit RGB value: 00224 void Adafruit_WS2801::setPixelColor(uint16_t n, uint32_t c) 00225 { 00226 if( n < numLEDs) { // Arrays are 0-indexed, thus NOT '<=' 00227 uint8_t *p = &pixels[n * 3]; 00228 // To keep the show() loop as simple & fast as possible, the 00229 // internal color representation is native to different pixel 00230 // types. For compatibility with existing code, 'packed' RGB 00231 // values passed in or out are always 0xRRGGBB order. 00232 if(rgb_order == WS2801_RGB) { 00233 *p++ = c >> 16; // Red 00234 *p++ = c >> 8; // Green 00235 } else { 00236 *p++ = c >> 8; // Green 00237 *p++ = c >> 16; // Red 00238 } 00239 *p++ = c; // Blue 00240 } 00241 } 00242 00243 // Set pixel color from 'packed' 32-bit RGB value using x,y coordinate system: 00244 void Adafruit_WS2801::setPixelColor(int16_t x, int16_t y, uint32_t c) 00245 { 00246 if( x < 0 || x >= width || y < 0 || y >= height ) 00247 return; // Dont try to update a pixel that doesnt exist 00248 00249 bool evenRow = ((y % 2) == 0); 00250 // calculate x offset first 00251 uint16_t offset = x % width; 00252 if (!evenRow) { 00253 offset = (width-1) - offset; 00254 } 00255 // add y offset 00256 offset += y * width; 00257 setPixelColor(offset, c); 00258 } 00259 00260 // Query color from previously-set pixel (returns packed 32-bit RGB value) 00261 uint32_t Adafruit_WS2801::getPixelColor(uint16_t n) 00262 { 00263 if(n < numLEDs) { 00264 uint16_t ofs = n * 3; 00265 // To keep the show() loop as simple & fast as possible, the 00266 // internal color representation is native to different pixel 00267 // types. For compatibility with existing code, 'packed' RGB 00268 // values passed in or out are always 0xRRGGBB order. 00269 return (rgb_order == WS2801_RGB) ? 00270 ((uint32_t)pixels[ofs] << 16) | ((uint16_t) pixels[ofs + 1] << 8) | pixels[ofs + 2] : 00271 (pixels[ofs] << 8) | ((uint32_t)pixels[ofs + 1] << 16) | pixels[ofs + 2]; 00272 } 00273 00274 return 0; // Pixel # is out of bounds 00275 } 00276 00277 // bresenham's algorithm - thx wikpedia 00278 void Adafruit_WS2801::drawLine(int16_t x0, int16_t y0, 00279 int16_t x1, int16_t y1, 00280 uint32_t color) { 00281 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00282 if (steep) { 00283 ws_swap(x0, y0); 00284 ws_swap(x1, y1); 00285 } 00286 00287 if (x0 > x1) { 00288 ws_swap(x0, x1); 00289 ws_swap(y0, y1); 00290 } 00291 00292 int16_t dx, dy; 00293 dx = x1 - x0; 00294 dy = abs(y1 - y0); 00295 00296 int16_t err = dx / 2; 00297 int16_t ystep; 00298 00299 if (y0 < y1) { 00300 ystep = 1; 00301 } else { 00302 ystep = -1; 00303 } 00304 00305 for (; x0<=x1; x0++) { 00306 if (steep) { 00307 setPixelColor(y0, x0, color); 00308 } else { 00309 setPixelColor(x0, y0, color); 00310 } 00311 err -= dy; 00312 if (err < 0) { 00313 y0 += ystep; 00314 err += dx; 00315 } 00316 } 00317 } 00318 00319 void Adafruit_WS2801::drawFastVLine(int16_t x, int16_t y, 00320 int16_t h, uint32_t color) { 00321 // stupidest version - update in subclasses if desired! 00322 drawLine(x, y, x, y+h-1, color); 00323 } 00324 00325 00326 void Adafruit_WS2801::drawFastHLine(int16_t x, int16_t y, 00327 int16_t w, uint32_t color) { 00328 // stupidest version - update in subclasses if desired! 00329 drawLine(x, y, x+w-1, y, color); 00330 } 00331 00332 00333 // draw a rectangle 00334 void Adafruit_WS2801::drawRect(int16_t x, int16_t y, 00335 int16_t w, int16_t h, uint32_t color) { 00336 drawFastHLine(x, y, w, color); 00337 drawFastHLine(x, y+h-1, w, color); 00338 drawFastVLine(x, y, h, color); 00339 drawFastVLine(x+w-1, y, h, color); 00340 } 00341 00342 // draw a circle outline 00343 void Adafruit_WS2801::drawCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color) { 00344 int16_t f = 1 - r; 00345 int16_t ddF_x = 1; 00346 int16_t ddF_y = -2 * r; 00347 int16_t x = 0; 00348 int16_t y = r; 00349 00350 setPixelColor(x0, y0+r, color); 00351 setPixelColor(x0, y0-r, color); 00352 setPixelColor(x0+r, y0, color); 00353 setPixelColor(x0-r, y0, color); 00354 00355 while (x<y) { 00356 if (f >= 0) { 00357 y--; 00358 ddF_y += 2; 00359 f += ddF_y; 00360 } 00361 x++; 00362 ddF_x += 2; 00363 f += ddF_x; 00364 00365 setPixelColor(x0 + x, y0 + y, color); 00366 setPixelColor(x0 - x, y0 + y, color); 00367 setPixelColor(x0 + x, y0 - y, color); 00368 setPixelColor(x0 - x, y0 - y, color); 00369 setPixelColor(x0 + y, y0 + x, color); 00370 setPixelColor(x0 - y, y0 + x, color); 00371 setPixelColor(x0 + y, y0 - x, color); 00372 setPixelColor(x0 - y, y0 - x, color); 00373 00374 } 00375 } 00376 /* 00377 void Adafruit_WS2801::fillCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color) { 00378 drawFastVLine(x0, y0-r, 2*r+1, color); 00379 fillCircleHelper(x0, y0, r, 3, 0, color); 00380 } 00381 00382 // used to do circles and roundrects! 00383 void Adafruit_WS2801::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, 00384 uint8_t cornername, int16_t delta, uint32_t color) { 00385 00386 int16_t f = 1 - r; 00387 int16_t ddF_x = 1; 00388 int16_t ddF_y = -2 * r; 00389 int16_t x = 0; 00390 int16_t y = r; 00391 00392 while (x<y) { 00393 if (f >= 0) { 00394 y--; 00395 ddF_y += 2; 00396 f += ddF_y; 00397 } 00398 x++; 00399 ddF_x += 2; 00400 f += ddF_x; 00401 00402 if (cornername & 0x1) { 00403 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00404 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00405 } 00406 if (cornername & 0x2) { 00407 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 00408 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 00409 } 00410 } 00411 } 00412 */
Generated on Fri Jul 15 2022 04:56:36 by 1.7.2