LED bus driver on any GPIO pin for addressable RGB LEDs (like NeoPixels or other WS2812 based LEDs)
LEDBus.cpp
- Committer:
- koengroener
- Date:
- 2017-06-14
- Revision:
- 3:67e68c46daef
- Parent:
- 2:735bb1b9cfc2
File content as of revision 3:67e68c46daef:
#include "LEDBus.h" LEDBus::LEDBus(PinName wirePin, ColorByteOrder byteOrder, float t0h_us, float t0l_us, float t1h_us, float t1l_us, float tReset_us) : _wire(wirePin) { float ticksPerMicroSecond = SystemCoreClock/MICRO_SECOND; _byteOrder = byteOrder; _delayT1H = ticksPerMicroSecond * t1h_us; _delayT0H = ticksPerMicroSecond * t0h_us; _delayT1L = ticksPerMicroSecond * t1l_us; _delayT0L = ticksPerMicroSecond * t0l_us; _delayReset = ticksPerMicroSecond * tReset_us; // Uncomment to see micro controller frequency and delays // Serial pc(USBTX, USBRX); // pc.printf("%d Hz\n\r", SystemCoreClock); // pc.printf("%f ticks/us\n\r", ticksPerMicroSecond); // pc.printf("T0H: %d ticks\n\r", _delayT0H); // pc.printf("T1H: %d ticks\n\r", _delayT1H); // pc.printf("T0L: %d ticks\n\r", _delayT0L); // pc.printf("T1L: %d ticks\n\r", _delayT1L); // pc.printf("Reset: %d ticks\n\r", _delayReset); } LEDBus::~LEDBus() { } void LEDBus::write(uint8_t byte) { for (int b = 7; b >= 0; b--) { bool bit = byte & (1 << b); _wire = 1; if (bit) { delay(_delayT1H); } else { delay(_delayT0H); } _wire = 0; if (bit) { delay(_delayT1L); } else { delay(_delayT0L); } } } void LEDBus::delay(unsigned const int ticks) { //loop_ticks is empirically determined (aka: works on my machine...) const int loop_ticks = 8; for (unsigned volatile int i = 0; i <= ticks-(loop_ticks/2); i+=loop_ticks) { /* nop */ } } void LEDBus::write(uint8_t* buffer, unsigned int size) { for (int i = 0; i < size; i++) { write(buffer[i]); } delay(_delayReset); } void LEDBus::write(Color** buffer, unsigned int size) { for (int i = 0; i < size; i++) { switch(_byteOrder) { case RGB: write(buffer[i]->red); write(buffer[i]->green); write(buffer[i]->blue); break; case RBG: write(buffer[i]->red); write(buffer[i]->blue); write(buffer[i]->green); break; case GRB: write(buffer[i]->green); write(buffer[i]->red); write(buffer[i]->blue); break; case GBR: write(buffer[i]->green); write(buffer[i]->blue); write(buffer[i]->red); break; case BRG: write(buffer[i]->blue); write(buffer[i]->red); write(buffer[i]->green); case BGR: write(buffer[i]->blue); write(buffer[i]->green); write(buffer[i]->red); break; } } delay(_delayReset); } void LEDBus::update(ColorGenerator generator, unsigned int numberOfLEDs) { unsigned char buffer[numberOfLEDs*3]; for (int i = 0; i < numberOfLEDs; i++) { Color* color = new Color(); generator(color, i); int ir,ig,ib; switch(_byteOrder) { case RGB: ir = 0; ig = 1; ib = 2; break; case RBG: ir = 0; ig = 2; ib = 1; break; case GRB: ir = 1; ig = 0; ib = 2; break; case GBR: ir = 2; ig = 0; ib = 1; break; case BRG: ir = 1; ig = 2; ib = 0; case BGR: ir = 2; ig = 1; ib = 0; break; } buffer[i*3 +ir] = color->red; buffer[i*3 +ig] = color->green; buffer[i*3 +ib] = color->blue; delete color; } write(buffer, numberOfLEDs*3); }