mbed Christmas tree using NeoPixel

Dependencies:   mbed

Fork of JBB_SerialLED_test by Junichi Katsu

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LEDStrip_WS2812.cpp Source File

LEDStrip_WS2812.cpp

00001 /*
00002  * WS2812 tape led IC
00003  *
00004  *          0.35us   0.8us    (+-150ns)
00005  *  0:     |^^^^^|__________|
00006  *
00007  *             0.7us   0.6us  (+-150ns)
00008  *  1:     |^^^^^^^^^^|_____|
00009  *
00010  *               >50us
00011  *  RESET: |________________|
00012  */
00013 #include "mbed.h"
00014 #include "LEDStrip.h"
00015 
00016 #if defined(TARGET_SSCI824)
00017 SPI tape(dp2, NC, NC);
00018 #else
00019 SPI tape(p11, NC, NC);
00020 #endif
00021 
00022 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00023     LPC_SSP_TypeDef *_ssp = LPC_SSP0;
00024 #elif defined(TARGET_LPC11U24)
00025     LPC_SSPx_Type *_ssp = LPC_SSP1;
00026 #elif defined(TARGET_SSCI824)
00027     LPC_SPI0_Type *_ssp = LPC_SPI0;
00028 #endif
00029 
00030 int num = 100;
00031 int *data;
00032 volatile int busy = 0, wakeup = 0;
00033 
00034 
00035 extern "C"
00036 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00037 void SSP0_IRQHandler() {
00038 #elif defined(TARGET_LPC11U24)
00039 void SSP1_IRQHandler() {
00040 #elif defined(TARGET_SSCI824)
00041 void SPI0_IRQHandler() {
00042 #endif
00043     static int addr = 0, bit = 0x800000;
00044 repeat:
00045 //printf("IRQ\n");
00046     if (busy) {
00047 //printf("busy\n");
00048         // led data
00049 #if defined(TARGET_SSCI824)
00050       while (_ssp->STAT & (1<<1)) { // TXRDY: Transmitter Ready flag.
00051 #else
00052       while (_ssp->SR & (1<<1)) { // TNF: Transmit FIFO Not Full
00053 #endif
00054 //printf("tx ready\n");
00055         if (data[addr] & bit) {
00056             // 1
00057             //_ssp->DR = 0x01f;
00058 #if defined(TARGET_SSCI824)
00059             _ssp->TXDAT = 0x007;
00060 #else
00061             _ssp->DR = 0x007;
00062 #endif
00063         } else {
00064             // 0
00065 #if (TARGET_SSCI824)
00066             _ssp->TXDAT = 0x07f;
00067 #else
00068             _ssp->DR = 0x07f;
00069 #endif
00070         }
00071         bit = bit >> 1;
00072         if (bit == 0) {
00073             bit = 0x800000;
00074             addr ++;
00075             if (addr >= num) {
00076                 addr = 0;
00077                 busy = 0;
00078                 goto repeat;
00079             }
00080         }
00081       }
00082     } else {
00083         // blank
00084 //printf("blank\n");
00085 #if defined(TARGET_SSCI824)
00086         while (_ssp->STAT & (1<<1)) { // TXRDY: Transmitter Ready flag.
00087             _ssp->TXDAT = 0xfff; // Data register
00088 #else
00089         while (_ssp->SR & (1<<1)) { // TNF: Transmit FIFO Not Full
00090             _ssp->DR = 0xfff; // Data register
00091 #endif
00092 //printf("tx ready\n");
00093             if (addr < 50) {
00094                 addr ++;
00095             } else {
00096                 addr = 0;
00097                 if (wakeup) {
00098                     busy = 1;
00099                     wakeup = 0;
00100                     goto repeat;
00101                 }
00102             }
00103         }
00104     }
00105 }
00106 
00107 void tapeInit (int freq, int n) {
00108 
00109     num = n;
00110 //    data = new int(num);
00111     data = (int*)malloc(sizeof(int) * num);
00112     for (int i = 0; i < num; i ++) {
00113         data[i] = 0;
00114     }
00115 
00116     tape.format(10, 1);
00117     if (freq) {
00118         tape.frequency(freq * 1000);
00119     } else {
00120         tape.frequency(8000000);
00121     }
00122 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00123     NVIC_SetVector(SSP0_IRQn, (uint32_t)SSP0_IRQHandler);
00124     NVIC_SetPriority(SSP0_IRQn, 0);
00125     NVIC_EnableIRQ(SSP0_IRQn);
00126 #elif defined(TARGET_LPC11U24)
00127     NVIC_SetVector(SSP1_IRQn, (uint32_t)SSP1_IRQHandler);
00128     NVIC_SetPriority(SSP1_IRQn, 0);
00129     NVIC_EnableIRQ(SSP1_IRQn);
00130 #elif defined(TARGET_SSCI824)
00131     NVIC_SetVector(SPI0_IRQn, (uint32_t)SPI0_IRQHandler);
00132     NVIC_SetPriority(SPI0_IRQn, 0);
00133     NVIC_EnableIRQ(SPI0_IRQn);
00134 #endif
00135 
00136 #if defined(TARGET_SSCI824)
00137     _ssp->INTENSET |= (1<<1); // TXRDYEN: An interrupt will be generated when data may be written to TXDAT.
00138 #else
00139     _ssp->IMSC |= (1<<3); // TXIM: to enable interrupt when the Tx FIFO is at least half empty.
00140 #endif
00141 }
00142 
00143 void tapeSet (int n, int dat) {
00144     if (n >= 0 && n < num) {
00145         // RGB -> GRB
00146         data[n] = ((dat & 0xff0000) >> 8) | ((dat & 0xff00) << 8) | (dat & 0xff);
00147     }
00148 }
00149 void tapeSet(int n, int red , int green , int blue) {
00150     if (n >= 0 && n < num) {
00151         // RGB -> GRB
00152         data[n] = ((red & 0xff) << 8) | ((green & 0xff) << 16) | (blue & 0xff);
00153     }
00154 }
00155 
00156 void tapeSend () {
00157     if (busy) {
00158         while (busy);
00159         wait_us(50);
00160     }
00161     wakeup = 1;
00162     while (wakeup);
00163 }
00164 
00165 int tapeGet (int n) {
00166     return ((data[n] & 0xff0000) >> 8) | ((data[n] & 0xff00) << 8) | (data[n] & 0xff);
00167 }