// WS2803_TestMBED.cpp
// By Thomas Olson
// teo20130210.01
// MBED LPC1768
// WS2803 pin4 CKI -> ws2803_clockPin(p21)
// WS2803 pin5 SDI -> ws2803_dataPin(p22)


#include "mbed.h"

DigitalOut ws2803_clockPin(p21);
DigitalOut ws2803_dataPin(p22);

#define nLEDs 18
#define nBARs 2         // Number of WS2803 chained together

uint8_t ledBar[nBARs][nLEDs];

void shiftOut(uint8_t sodata) {
    for(int i = 7; i >= 0; i--) {
        ws2803_clockPin = 0;
        if(sodata & (0x01 << i)){
            ws2803_dataPin = 1;
        } else {
            ws2803_dataPin = 0;
        }
        wait_us(1);
        ws2803_clockPin = 1;
        wait_us(1);
        ws2803_clockPin = 0;
    }
}

void loadWS2803(){
  for(int wsBar = 0; wsBar < nBARs; wsBar++){
    for (int wsOut = 0; wsOut < nLEDs; wsOut++){
      shiftOut(ledBar[nBARs-(wsBar+1)][wsOut]);
    }
  }
  ws2803_clockPin = 0;
  wait_us(600); // 500us-600us needed to reset WS2803s
}

void clearWS2803(){
        for(int wsOut = 0; wsOut < nLEDs; wsOut++){
                ledBar[0][wsOut] = ledBar[1][wsOut] = 0x00;
                loadWS2803();
        }
}

int main() {
    // initialize WS2803s
    ws2803_clockPin = 0;
    wait_us(600);
   
    while(1) {
        clearWS2803();
        wait(2.0);
        // Chase mode
        for(int iOut=7; iOut < 256; iOut*=2){
            for(int wsOut = 0; wsOut < nLEDs; wsOut++){
                ledBar[0][wsOut] = ledBar[1][wsOut] = (uint8_t)(0xFF & iOut);
                loadWS2803();
                clearWS2803();
            }
        }

        wait(2.0);    
        //parallel mode
        for(int iOut = 7; iOut < 64; iOut*=4){
                for(int wsOut = 0; wsOut < nLEDs; wsOut++){
                        ledBar[0][wsOut] = ledBar[1][wsOut] = (uint8_t)(0xFF & iOut);
                        loadWS2803();
                        wait_us(1000000);
                }
                wait_us(10000);
        }
    }// while(1)
}

