Heroic Robotics / SD600A

Fork of SD600A by Heroic Robotics

Committer:
heroic
Date:
Wed Oct 10 06:36:39 2012 +0000
Revision:
15:2733cd5f34e4
Parent:
14:908869a15f5a
Child:
16:910bf46f2ce4
Don't diddle the ethernet priority-  not necessary.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
heroic 12:08d02c0aaa67 1 // Mbed library to control SD600A-based RGB LED Strips
heroic 12:08d02c0aaa67 2 // Partially based on work (c) 2011 Jelmer Tiete
heroic 12:08d02c0aaa67 3 //
heroic 12:08d02c0aaa67 4 // Ported from Arduino by
heroic 12:08d02c0aaa67 5 // Jas Strong <jasmine@electronpusher.org>
heroic 12:08d02c0aaa67 6 /*****************************************************************************/
heroic 12:08d02c0aaa67 7
heroic 12:08d02c0aaa67 8 #include "rtos.h"
heroic 12:08d02c0aaa67 9 #include "LedStrip.h"
heroic 12:08d02c0aaa67 10 #include "SD600A.h"
heroic 12:08d02c0aaa67 11
heroic 12:08d02c0aaa67 12 void SD600A::idle_function(void) {
heroic 12:08d02c0aaa67 13 dat = 0;
heroic 12:08d02c0aaa67 14 clk = !clk;
heroic 12:08d02c0aaa67 15 }
heroic 12:08d02c0aaa67 16
heroic 12:08d02c0aaa67 17 SD600A::SD600A(PinName dataPin, PinName clockPin, int n) :
heroic 12:08d02c0aaa67 18 dat(dataPin),
heroic 12:08d02c0aaa67 19 clk(clockPin) {
heroic 12:08d02c0aaa67 20 // Allocate 3 bytes per pixel:
heroic 12:08d02c0aaa67 21 numLEDs = n;
heroic 12:08d02c0aaa67 22 if ((pixels = (uint8_t *)malloc(numLEDs * 3))) {
heroic 12:08d02c0aaa67 23 memset(pixels, 0, numLEDs * 3); // Init to RGB 'off' state
heroic 12:08d02c0aaa67 24 }
heroic 12:08d02c0aaa67 25 idletoggle.attach_us(this, &SD600A::idle_function, IDLE_INTERVAL);
heroic 12:08d02c0aaa67 26 }
heroic 12:08d02c0aaa67 27
heroic 12:08d02c0aaa67 28 /*
heroic 13:875eb971d6c6 29 * Soft SPI clock-out implementation (CPOL = 1, CPHA = 0).
heroic 12:08d02c0aaa67 30 * Certainly not the fastest in the world but it'll do.
heroic 12:08d02c0aaa67 31 * Gets about 3.6 MHz; could get several times as much
heroic 12:08d02c0aaa67 32 * using the bitbands directly - jas.
heroic 12:08d02c0aaa67 33 */
heroic 12:08d02c0aaa67 34
heroic 12:08d02c0aaa67 35 void SD600A::write(uint8_t byte) {
heroic 12:08d02c0aaa67 36 clk=1;
heroic 12:08d02c0aaa67 37 for (int i=0; i<8; i++) {
heroic 12:08d02c0aaa67 38 dat = !!(byte & (1 << (7 - i)));
heroic 12:08d02c0aaa67 39
heroic 12:08d02c0aaa67 40 clk = 0;
heroic 12:08d02c0aaa67 41 // dat = (byte & 0x80);
heroic 12:08d02c0aaa67 42 #ifdef DELAY_PERIOD
heroic 12:08d02c0aaa67 43 wait_us(DELAY_PERIOD);
heroic 12:08d02c0aaa67 44 #endif
heroic 12:08d02c0aaa67 45 clk = 1;
heroic 12:08d02c0aaa67 46 #ifdef DELAY_PERIOD
heroic 12:08d02c0aaa67 47 wait_us(DELAY_PERIOD);
heroic 12:08d02c0aaa67 48 #endif
heroic 12:08d02c0aaa67 49 //byte <<= 1;
heroic 12:08d02c0aaa67 50 }
heroic 12:08d02c0aaa67 51 }
heroic 12:08d02c0aaa67 52
heroic 12:08d02c0aaa67 53 void SD600A::begin(void) {
heroic 12:08d02c0aaa67 54 // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs)
heroic 12:08d02c0aaa67 55 idletoggle.detach();
heroic 15:2733cd5f34e4 56 // set the Ticker interrupt to the highest possible priority
heroic 14:908869a15f5a 57 NVIC_SetPriority(TIMER3_IRQn, 0);
heroic 12:08d02c0aaa67 58 for (int i=0; i<numLEDs; i++) {
heroic 12:08d02c0aaa67 59 write(0);
heroic 12:08d02c0aaa67 60 write(0);
heroic 12:08d02c0aaa67 61 write(0);
heroic 12:08d02c0aaa67 62 }
heroic 12:08d02c0aaa67 63 writeguard();
heroic 12:08d02c0aaa67 64 idletoggle.attach_us(this, &SD600A::idle_function, IDLE_INTERVAL);
heroic 12:08d02c0aaa67 65 }
heroic 12:08d02c0aaa67 66
heroic 12:08d02c0aaa67 67 uint16_t SD600A::numPixels(void) {
heroic 12:08d02c0aaa67 68 return numLEDs;
heroic 12:08d02c0aaa67 69 }
heroic 12:08d02c0aaa67 70
heroic 12:08d02c0aaa67 71 void SD600A::writeguard(void) {
heroic 12:08d02c0aaa67 72 // generate a 25-bit word of ones
heroic 13:875eb971d6c6 73 clk = 1;
heroic 12:08d02c0aaa67 74 #ifdef DELAY_PERIOD
heroic 12:08d02c0aaa67 75 wait_us(DELAY_PERIOD);
heroic 12:08d02c0aaa67 76 #endif
heroic 12:08d02c0aaa67 77 dat = 1;
heroic 12:08d02c0aaa67 78 #ifdef DELAY_PERIOD
heroic 12:08d02c0aaa67 79 wait_us(DELAY_PERIOD);
heroic 12:08d02c0aaa67 80 #endif
heroic 13:875eb971d6c6 81 clk = 0;
heroic 12:08d02c0aaa67 82 #ifdef DELAY_PERIOD
heroic 12:08d02c0aaa67 83 wait_us(DELAY_PERIOD);
heroic 12:08d02c0aaa67 84 #endif
heroic 12:08d02c0aaa67 85 write(0xff);
heroic 12:08d02c0aaa67 86 write(0xff);
heroic 12:08d02c0aaa67 87 write(0xff);
heroic 12:08d02c0aaa67 88 }
heroic 12:08d02c0aaa67 89
heroic 12:08d02c0aaa67 90 void SD600A::blank(void) {
heroic 12:08d02c0aaa67 91 memset(pixels, 0x00, numLEDs * 3);
heroic 12:08d02c0aaa67 92 }
heroic 12:08d02c0aaa67 93
heroic 12:08d02c0aaa67 94 void SD600A::show(void) {
heroic 12:08d02c0aaa67 95 uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
heroic 12:08d02c0aaa67 96 idletoggle.detach();
heroic 12:08d02c0aaa67 97
heroic 12:08d02c0aaa67 98 for (i=nl3; i; i-- ) {
heroic 12:08d02c0aaa67 99 write(pixels[i]);
heroic 12:08d02c0aaa67 100 }
heroic 12:08d02c0aaa67 101
heroic 12:08d02c0aaa67 102 // Write guard word
heroic 12:08d02c0aaa67 103 writeguard();
heroic 12:08d02c0aaa67 104 idletoggle.attach_us(this, &SD600A::idle_function, IDLE_INTERVAL);
heroic 12:08d02c0aaa67 105 }
heroic 12:08d02c0aaa67 106
heroic 12:08d02c0aaa67 107 // Convert R,G,B to combined 32-bit color
heroic 12:08d02c0aaa67 108 uint32_t SD600A::Color(uint8_t r, uint8_t g, uint8_t b) {
heroic 12:08d02c0aaa67 109 // Take 23 bits of the value and append them end to end
heroic 12:08d02c0aaa67 110 // We cannot drive all ones or it will make the part latch if the previous word ended in one!
heroic 12:08d02c0aaa67 111 return 0xfefefe & ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b;
heroic 12:08d02c0aaa67 112 }
heroic 12:08d02c0aaa67 113
heroic 12:08d02c0aaa67 114 // store the rgb component in our array
heroic 12:08d02c0aaa67 115 void SD600A::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
heroic 12:08d02c0aaa67 116 if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
heroic 12:08d02c0aaa67 117
heroic 12:08d02c0aaa67 118 pixels[n*3 ] = b & 0xfe;
heroic 12:08d02c0aaa67 119 pixels[n*3+1] = g & 0xfe;
heroic 12:08d02c0aaa67 120 pixels[n*3+2] = r & 0xfe;
heroic 12:08d02c0aaa67 121 }
heroic 12:08d02c0aaa67 122
heroic 12:08d02c0aaa67 123 void SD600A::setPixelR(uint16_t n, uint8_t r) {
heroic 12:08d02c0aaa67 124 if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
heroic 12:08d02c0aaa67 125
heroic 12:08d02c0aaa67 126 pixels[n*3+2] = r & 0xfe;
heroic 12:08d02c0aaa67 127 }
heroic 12:08d02c0aaa67 128
heroic 12:08d02c0aaa67 129 void SD600A::setPixelG(uint16_t n, uint8_t g) {
heroic 12:08d02c0aaa67 130 if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
heroic 12:08d02c0aaa67 131
heroic 12:08d02c0aaa67 132 pixels[n*3+1] = g & 0xfe;
heroic 12:08d02c0aaa67 133 }
heroic 12:08d02c0aaa67 134
heroic 12:08d02c0aaa67 135 void SD600A::setPixelB(uint16_t n, uint8_t b) {
heroic 12:08d02c0aaa67 136 if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
heroic 12:08d02c0aaa67 137
heroic 12:08d02c0aaa67 138 pixels[n*3] = b & 0xfe;
heroic 12:08d02c0aaa67 139 }
heroic 12:08d02c0aaa67 140
heroic 12:08d02c0aaa67 141 void SD600A::setPixelColor(uint16_t n, uint32_t c) {
heroic 12:08d02c0aaa67 142 if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
heroic 12:08d02c0aaa67 143
heroic 12:08d02c0aaa67 144 pixels[n*3 ] = (c >> 16) & 0xfe;
heroic 12:08d02c0aaa67 145 pixels[n*3+1] = (c >> 8) & 0xfe;
heroic 12:08d02c0aaa67 146 pixels[n*3+2] = c & 0xfe;
heroic 12:08d02c0aaa67 147 }