Library and demo using the WS2812-based Neopixel strip connected to an LPC114
Fork of LEDTape_WS2812 by
Details here: http://mbed.org/users/rhodes42/notebook/tiny-neopixel-controller-with-lpc1114/
LEDStrip_WS2812.cpp@1:71b32479b674, 2014-03-24 (annotated)
- Committer:
- rhodes42
- Date:
- Mon Mar 24 08:06:29 2014 +0000
- Revision:
- 1:71b32479b674
- Parent:
- 0:d067ddfe3df9
working non-inverted WS2812 driver;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okini3939 | 0:d067ddfe3df9 | 1 | /* |
okini3939 | 0:d067ddfe3df9 | 2 | * WS2812 tape led IC |
okini3939 | 0:d067ddfe3df9 | 3 | * |
okini3939 | 0:d067ddfe3df9 | 4 | * 0.35us 0.8us (+-150ns) |
okini3939 | 0:d067ddfe3df9 | 5 | * 0: |^^^^^|__________| |
okini3939 | 0:d067ddfe3df9 | 6 | * |
okini3939 | 0:d067ddfe3df9 | 7 | * 0.7us 0.6us (+-150ns) |
okini3939 | 0:d067ddfe3df9 | 8 | * 1: |^^^^^^^^^^|_____| |
okini3939 | 0:d067ddfe3df9 | 9 | * |
okini3939 | 0:d067ddfe3df9 | 10 | * >50us |
okini3939 | 0:d067ddfe3df9 | 11 | * RESET: |________________| |
okini3939 | 0:d067ddfe3df9 | 12 | */ |
okini3939 | 0:d067ddfe3df9 | 13 | #include "mbed.h" |
okini3939 | 0:d067ddfe3df9 | 14 | #include "LEDStrip.h" |
okini3939 | 0:d067ddfe3df9 | 15 | |
rhodes42 | 1:71b32479b674 | 16 | SPI tape(dp2, dp1, dp6); |
okini3939 | 0:d067ddfe3df9 | 17 | |
rhodes42 | 1:71b32479b674 | 18 | #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC1114) |
okini3939 | 0:d067ddfe3df9 | 19 | LPC_SSP_TypeDef *_ssp = LPC_SSP0; |
rhodes42 | 1:71b32479b674 | 20 | #elif defined(TARGET_LPC11U24) |
okini3939 | 0:d067ddfe3df9 | 21 | LPC_SSPx_Type *_ssp = LPC_SSP1; |
okini3939 | 0:d067ddfe3df9 | 22 | #endif |
okini3939 | 0:d067ddfe3df9 | 23 | |
okini3939 | 0:d067ddfe3df9 | 24 | int num = 100; |
okini3939 | 0:d067ddfe3df9 | 25 | int *data; |
okini3939 | 0:d067ddfe3df9 | 26 | volatile int busy = 0, wakeup = 0; |
okini3939 | 0:d067ddfe3df9 | 27 | |
okini3939 | 0:d067ddfe3df9 | 28 | |
okini3939 | 0:d067ddfe3df9 | 29 | extern "C" |
rhodes42 | 1:71b32479b674 | 30 | #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)|| defined(TARGET_LPC1114) |
okini3939 | 0:d067ddfe3df9 | 31 | void SSP0_IRQHandler() { |
rhodes42 | 1:71b32479b674 | 32 | #elif defined(TARGET_LPC11U24) |
okini3939 | 0:d067ddfe3df9 | 33 | void SSP1_IRQHandler() { |
okini3939 | 0:d067ddfe3df9 | 34 | #endif |
okini3939 | 0:d067ddfe3df9 | 35 | static int addr = 0, bit = 0x800000; |
okini3939 | 0:d067ddfe3df9 | 36 | repeat: |
okini3939 | 0:d067ddfe3df9 | 37 | if (busy) { |
okini3939 | 0:d067ddfe3df9 | 38 | // led data |
okini3939 | 0:d067ddfe3df9 | 39 | while (_ssp->SR & (1<<1)) { // TNF |
okini3939 | 0:d067ddfe3df9 | 40 | if (data[addr] & bit) { |
okini3939 | 0:d067ddfe3df9 | 41 | // 1 |
rhodes42 | 1:71b32479b674 | 42 | _ssp->DR = 0x3f8; //07f |
okini3939 | 0:d067ddfe3df9 | 43 | } else { |
okini3939 | 0:d067ddfe3df9 | 44 | // 0 |
rhodes42 | 1:71b32479b674 | 45 | _ssp->DR = 0x380; //0077 |
okini3939 | 0:d067ddfe3df9 | 46 | } |
okini3939 | 0:d067ddfe3df9 | 47 | bit = bit >> 1; |
okini3939 | 0:d067ddfe3df9 | 48 | if (bit == 0) { |
okini3939 | 0:d067ddfe3df9 | 49 | bit = 0x800000; |
okini3939 | 0:d067ddfe3df9 | 50 | addr ++; |
okini3939 | 0:d067ddfe3df9 | 51 | if (addr >= num) { |
okini3939 | 0:d067ddfe3df9 | 52 | addr = 0; |
okini3939 | 0:d067ddfe3df9 | 53 | busy = 0; |
okini3939 | 0:d067ddfe3df9 | 54 | goto repeat; |
okini3939 | 0:d067ddfe3df9 | 55 | } |
okini3939 | 0:d067ddfe3df9 | 56 | } |
okini3939 | 0:d067ddfe3df9 | 57 | } |
okini3939 | 0:d067ddfe3df9 | 58 | } else { |
okini3939 | 0:d067ddfe3df9 | 59 | // blank |
okini3939 | 0:d067ddfe3df9 | 60 | while (_ssp->SR & (1<<1)) { // TNF |
rhodes42 | 1:71b32479b674 | 61 | _ssp->DR = 0x000; |
okini3939 | 0:d067ddfe3df9 | 62 | if (addr < 50) { |
okini3939 | 0:d067ddfe3df9 | 63 | addr ++; |
okini3939 | 0:d067ddfe3df9 | 64 | } else { |
okini3939 | 0:d067ddfe3df9 | 65 | addr = 0; |
okini3939 | 0:d067ddfe3df9 | 66 | if (wakeup) { |
okini3939 | 0:d067ddfe3df9 | 67 | busy = 1; |
okini3939 | 0:d067ddfe3df9 | 68 | wakeup = 0; |
okini3939 | 0:d067ddfe3df9 | 69 | goto repeat; |
okini3939 | 0:d067ddfe3df9 | 70 | } |
okini3939 | 0:d067ddfe3df9 | 71 | } |
okini3939 | 0:d067ddfe3df9 | 72 | } |
okini3939 | 0:d067ddfe3df9 | 73 | } |
okini3939 | 0:d067ddfe3df9 | 74 | } |
okini3939 | 0:d067ddfe3df9 | 75 | |
okini3939 | 0:d067ddfe3df9 | 76 | void tapeInit (int freq, int n) { |
okini3939 | 0:d067ddfe3df9 | 77 | |
okini3939 | 0:d067ddfe3df9 | 78 | num = n; |
okini3939 | 0:d067ddfe3df9 | 79 | // data = new int(num); |
okini3939 | 0:d067ddfe3df9 | 80 | data = (int*)malloc(sizeof(int) * num); |
okini3939 | 0:d067ddfe3df9 | 81 | for (int i = 0; i < num; i ++) { |
okini3939 | 0:d067ddfe3df9 | 82 | data[i] = 0; |
okini3939 | 0:d067ddfe3df9 | 83 | } |
okini3939 | 0:d067ddfe3df9 | 84 | |
okini3939 | 0:d067ddfe3df9 | 85 | tape.format(10, 1); |
okini3939 | 0:d067ddfe3df9 | 86 | if (freq) { |
okini3939 | 0:d067ddfe3df9 | 87 | tape.frequency(freq * 1000); |
okini3939 | 0:d067ddfe3df9 | 88 | } else { |
okini3939 | 0:d067ddfe3df9 | 89 | tape.frequency(8000000); |
okini3939 | 0:d067ddfe3df9 | 90 | } |
rhodes42 | 1:71b32479b674 | 91 | #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC1114) |
okini3939 | 0:d067ddfe3df9 | 92 | NVIC_SetVector(SSP0_IRQn, (uint32_t)SSP0_IRQHandler); |
okini3939 | 0:d067ddfe3df9 | 93 | NVIC_SetPriority(SSP0_IRQn, 0); |
okini3939 | 0:d067ddfe3df9 | 94 | NVIC_EnableIRQ(SSP0_IRQn); |
okini3939 | 0:d067ddfe3df9 | 95 | #elif defined(TARGET_LPC11U24) |
okini3939 | 0:d067ddfe3df9 | 96 | NVIC_SetVector(SSP1_IRQn, (uint32_t)SSP1_IRQHandler); |
okini3939 | 0:d067ddfe3df9 | 97 | NVIC_SetPriority(SSP1_IRQn, 0); |
okini3939 | 0:d067ddfe3df9 | 98 | NVIC_EnableIRQ(SSP1_IRQn); |
okini3939 | 0:d067ddfe3df9 | 99 | #endif |
okini3939 | 0:d067ddfe3df9 | 100 | _ssp->IMSC |= (1<<3); // TXIM |
okini3939 | 0:d067ddfe3df9 | 101 | } |
okini3939 | 0:d067ddfe3df9 | 102 | |
okini3939 | 0:d067ddfe3df9 | 103 | void tapeSet (int n, int dat) { |
okini3939 | 0:d067ddfe3df9 | 104 | if (n >= 0 && n < num) { |
okini3939 | 0:d067ddfe3df9 | 105 | // RGB -> GRB |
okini3939 | 0:d067ddfe3df9 | 106 | data[n] = ((dat & 0xff0000) >> 8) | ((dat & 0xff00) << 8) | (dat & 0xff); |
okini3939 | 0:d067ddfe3df9 | 107 | } |
okini3939 | 0:d067ddfe3df9 | 108 | } |
okini3939 | 0:d067ddfe3df9 | 109 | |
okini3939 | 0:d067ddfe3df9 | 110 | void tapeSend () { |
okini3939 | 0:d067ddfe3df9 | 111 | if (busy) { |
okini3939 | 0:d067ddfe3df9 | 112 | while (busy); |
okini3939 | 0:d067ddfe3df9 | 113 | wait_us(50); |
okini3939 | 0:d067ddfe3df9 | 114 | } |
okini3939 | 0:d067ddfe3df9 | 115 | wakeup = 1; |
okini3939 | 0:d067ddfe3df9 | 116 | while (wakeup); |
okini3939 | 0:d067ddfe3df9 | 117 | } |
okini3939 | 0:d067ddfe3df9 | 118 | |
okini3939 | 0:d067ddfe3df9 | 119 | int tapeGet (int n) { |
okini3939 | 0:d067ddfe3df9 | 120 | return ((data[n] & 0xff0000) >> 8) | ((data[n] & 0xff00) << 8) | (data[n] & 0xff); |
okini3939 | 0:d067ddfe3df9 | 121 | } |