LED bus driver on any GPIO pin for addressable RGB LEDs (like NeoPixels or other WS2812 based LEDs)

Committer:
koengroener
Date:
Tue May 10 20:07:28 2016 +0000
Revision:
0:1e68c70236a4
Child:
1:6119419c2730
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
koengroener 0:1e68c70236a4 1 #include "LEDBus.h"
koengroener 0:1e68c70236a4 2
koengroener 0:1e68c70236a4 3
koengroener 0:1e68c70236a4 4
koengroener 0:1e68c70236a4 5
koengroener 0:1e68c70236a4 6 LEDBus::LEDBus(PinName wirePin, ByteOrder byteOrder, float t0h_us, float t0l_us, float t1h_us, float t1l_us, float tReset_us) : _wire(wirePin)
koengroener 0:1e68c70236a4 7 {
koengroener 0:1e68c70236a4 8 float ticksPerMicroSecond = SystemCoreClock/MICRO_SECOND;
koengroener 0:1e68c70236a4 9
koengroener 0:1e68c70236a4 10 _byteOrder = byteOrder;
koengroener 0:1e68c70236a4 11
koengroener 0:1e68c70236a4 12 _delayT1H = ticksPerMicroSecond * t1h_us;
koengroener 0:1e68c70236a4 13 _delayT0H = ticksPerMicroSecond * t0h_us;
koengroener 0:1e68c70236a4 14 _delayT1L = ticksPerMicroSecond * t1l_us;
koengroener 0:1e68c70236a4 15 _delayT0L = ticksPerMicroSecond * t0l_us;
koengroener 0:1e68c70236a4 16
koengroener 0:1e68c70236a4 17 _delayReset = ticksPerMicroSecond * tReset_us;
koengroener 0:1e68c70236a4 18
koengroener 0:1e68c70236a4 19 // Uncomment to see micro controller frequency and delays
koengroener 0:1e68c70236a4 20 Serial pc(USBTX, USBRX);
koengroener 0:1e68c70236a4 21 pc.printf("%d Hz\n\r", SystemCoreClock);
koengroener 0:1e68c70236a4 22 pc.printf("%f ticks/us\n\r", ticksPerMicroSecond);
koengroener 0:1e68c70236a4 23 pc.printf("T0H: %d ticks\n\r", _delayT0H);
koengroener 0:1e68c70236a4 24 pc.printf("T1H: %d ticks\n\r", _delayT1H);
koengroener 0:1e68c70236a4 25 pc.printf("T0L: %d ticks\n\r", _delayT0L);
koengroener 0:1e68c70236a4 26 pc.printf("T1L: %d ticks\n\r", _delayT1L);
koengroener 0:1e68c70236a4 27 pc.printf("Reset: %d ticks\n\r", _delayReset);
koengroener 0:1e68c70236a4 28
koengroener 0:1e68c70236a4 29 }
koengroener 0:1e68c70236a4 30
koengroener 0:1e68c70236a4 31 LEDBus::~LEDBus()
koengroener 0:1e68c70236a4 32 {
koengroener 0:1e68c70236a4 33 }
koengroener 0:1e68c70236a4 34
koengroener 0:1e68c70236a4 35 void LEDBus::write(uint8_t byte)
koengroener 0:1e68c70236a4 36 {
koengroener 0:1e68c70236a4 37 for (int b = 7; b >= 0; b--) {
koengroener 0:1e68c70236a4 38 bool bit = byte & (1 << b);
koengroener 0:1e68c70236a4 39
koengroener 0:1e68c70236a4 40 _wire = 1;
koengroener 0:1e68c70236a4 41
koengroener 0:1e68c70236a4 42 if (bit) {
koengroener 0:1e68c70236a4 43 delay(_delayT1H);
koengroener 0:1e68c70236a4 44 } else {
koengroener 0:1e68c70236a4 45 delay(_delayT0H);
koengroener 0:1e68c70236a4 46 }
koengroener 0:1e68c70236a4 47
koengroener 0:1e68c70236a4 48 _wire = 0;
koengroener 0:1e68c70236a4 49
koengroener 0:1e68c70236a4 50 if (bit) {
koengroener 0:1e68c70236a4 51 delay(_delayT1L);
koengroener 0:1e68c70236a4 52 } else {
koengroener 0:1e68c70236a4 53 delay(_delayT0L);
koengroener 0:1e68c70236a4 54 }
koengroener 0:1e68c70236a4 55 }
koengroener 0:1e68c70236a4 56 }
koengroener 0:1e68c70236a4 57
koengroener 0:1e68c70236a4 58 void LEDBus::delay(unsigned int ticks)
koengroener 0:1e68c70236a4 59 {
koengroener 0:1e68c70236a4 60 // each loop should be around 6 clock cycles...
koengroener 0:1e68c70236a4 61 for (unsigned volatile int i = 0; i < ticks; i+=6) {
koengroener 0:1e68c70236a4 62 /* nop */
koengroener 0:1e68c70236a4 63 }
koengroener 0:1e68c70236a4 64 }
koengroener 0:1e68c70236a4 65
koengroener 0:1e68c70236a4 66 void LEDBus::write(uint8_t* buffer, unsigned int size)
koengroener 0:1e68c70236a4 67 {
koengroener 0:1e68c70236a4 68 for (int i = 0; i < size; i++) {
koengroener 0:1e68c70236a4 69 write(buffer[i]);
koengroener 0:1e68c70236a4 70 }
koengroener 0:1e68c70236a4 71
koengroener 0:1e68c70236a4 72 delay(_delayReset);
koengroener 0:1e68c70236a4 73 }
koengroener 0:1e68c70236a4 74
koengroener 0:1e68c70236a4 75 void LEDBus::write(Color** buffer, unsigned int size)
koengroener 0:1e68c70236a4 76 {
koengroener 0:1e68c70236a4 77 for (int i = 0; i < size; i++) {
koengroener 0:1e68c70236a4 78 switch(_byteOrder) {
koengroener 0:1e68c70236a4 79 case RGB:
koengroener 0:1e68c70236a4 80 write(buffer[i]->red);
koengroener 0:1e68c70236a4 81 write(buffer[i]->green);
koengroener 0:1e68c70236a4 82 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 83 break;
koengroener 0:1e68c70236a4 84 case RBG:
koengroener 0:1e68c70236a4 85 write(buffer[i]->red);
koengroener 0:1e68c70236a4 86 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 87 write(buffer[i]->green);
koengroener 0:1e68c70236a4 88 break;
koengroener 0:1e68c70236a4 89 case GRB:
koengroener 0:1e68c70236a4 90 write(buffer[i]->green);
koengroener 0:1e68c70236a4 91 write(buffer[i]->red);
koengroener 0:1e68c70236a4 92 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 93 break;
koengroener 0:1e68c70236a4 94 case GBR:
koengroener 0:1e68c70236a4 95 write(buffer[i]->green);
koengroener 0:1e68c70236a4 96 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 97 write(buffer[i]->red);
koengroener 0:1e68c70236a4 98 break;
koengroener 0:1e68c70236a4 99 case BRG:
koengroener 0:1e68c70236a4 100 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 101 write(buffer[i]->red);
koengroener 0:1e68c70236a4 102 write(buffer[i]->green);
koengroener 0:1e68c70236a4 103 case BGR:
koengroener 0:1e68c70236a4 104 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 105 write(buffer[i]->green);
koengroener 0:1e68c70236a4 106 write(buffer[i]->red);
koengroener 0:1e68c70236a4 107 break;
koengroener 0:1e68c70236a4 108 }
koengroener 0:1e68c70236a4 109
koengroener 0:1e68c70236a4 110 }
koengroener 0:1e68c70236a4 111
koengroener 0:1e68c70236a4 112 delay(_delayReset);
koengroener 0:1e68c70236a4 113 }
koengroener 0:1e68c70236a4 114
koengroener 0:1e68c70236a4 115
koengroener 0:1e68c70236a4 116 void LEDBus::update(ColorGenerator generator, unsigned int numberOfLEDs)
koengroener 0:1e68c70236a4 117 {
koengroener 0:1e68c70236a4 118 unsigned char buffer[numberOfLEDs*3];
koengroener 0:1e68c70236a4 119
koengroener 0:1e68c70236a4 120 for (int i = 0; i < numberOfLEDs; i++) {
koengroener 0:1e68c70236a4 121 Color* color = new Color();
koengroener 0:1e68c70236a4 122 generator(color, i);
koengroener 0:1e68c70236a4 123
koengroener 0:1e68c70236a4 124 int ir,ig,ib;
koengroener 0:1e68c70236a4 125
koengroener 0:1e68c70236a4 126 switch(_byteOrder) {
koengroener 0:1e68c70236a4 127 case RGB:
koengroener 0:1e68c70236a4 128 ir = 0;
koengroener 0:1e68c70236a4 129 ig = 1;
koengroener 0:1e68c70236a4 130 ib = 2;
koengroener 0:1e68c70236a4 131 break;
koengroener 0:1e68c70236a4 132 case RBG:
koengroener 0:1e68c70236a4 133 ir = 0;
koengroener 0:1e68c70236a4 134 ig = 2;
koengroener 0:1e68c70236a4 135 ib = 1;
koengroener 0:1e68c70236a4 136 break;
koengroener 0:1e68c70236a4 137 case GRB:
koengroener 0:1e68c70236a4 138 ir = 1;
koengroener 0:1e68c70236a4 139 ig = 0;
koengroener 0:1e68c70236a4 140 ib = 2;
koengroener 0:1e68c70236a4 141 break;
koengroener 0:1e68c70236a4 142 case GBR:
koengroener 0:1e68c70236a4 143 ir = 2;
koengroener 0:1e68c70236a4 144 ig = 0;
koengroener 0:1e68c70236a4 145 ib = 1;
koengroener 0:1e68c70236a4 146 break;
koengroener 0:1e68c70236a4 147 case BRG:
koengroener 0:1e68c70236a4 148 ir = 1;
koengroener 0:1e68c70236a4 149 ig = 2;
koengroener 0:1e68c70236a4 150 ib = 0;
koengroener 0:1e68c70236a4 151 case BGR:
koengroener 0:1e68c70236a4 152 ir = 2;
koengroener 0:1e68c70236a4 153 ig = 1;
koengroener 0:1e68c70236a4 154 ib = 0;
koengroener 0:1e68c70236a4 155 break;
koengroener 0:1e68c70236a4 156 }
koengroener 0:1e68c70236a4 157
koengroener 0:1e68c70236a4 158 buffer[i*3 +ir] = color->red;
koengroener 0:1e68c70236a4 159 buffer[i*3 +ig] = color->green;
koengroener 0:1e68c70236a4 160 buffer[i*3 +ib] = color->blue;
koengroener 0:1e68c70236a4 161
koengroener 0:1e68c70236a4 162 delete color;
koengroener 0:1e68c70236a4 163 }
koengroener 0:1e68c70236a4 164
koengroener 0:1e68c70236a4 165 write(buffer, numberOfLEDs*3);
koengroener 0:1e68c70236a4 166 }
koengroener 0:1e68c70236a4 167
koengroener 0:1e68c70236a4 168