Rev 282 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include "defines.h"#include "NEOPIXEL.h"extern NEOPIXEL_DATA neopixel_data;void NeoPixel_Init(void) {// Clear bufferfor (uint8_t i = 0; i < NEOPIXEL_LENGTH * 3; i++) {neopixel_data.values[i] = 0x0;}neopixel_data.offset = 0;// Output pin initially blockedNEOPIXEL_TRIS = 1;/* Initialize PWM module */PR2 = 0x09; // 1.25us @ 32MHzCCP1CONbits.P1M = 0b00; // Single output, P1A modulated onlyCCP1CONbits.CCP1M = 0b1100; // PWM mode, P1A active-high, P1B active-high// Idle the output till width is specifiedCCPR1L = 0x00;CCP1CONbits.DC1B = 0b00;/* Initialize Timer 2 */PIR1bits.TMR2IF = 0; // Clear the interrupt flag for Timer 2T2CONbits.T2CKPS = 0b00; // Set a prescaler of 1:1T2CONbits.TMR2ON = 1; // Enable the timer// Wait for the timer to overflow before enabling outputwhile (!PIR1bits.TMR2IF);NEOPIXEL_TRIS = 0;}void NeoPixel_Offet(uint8_t value) {neopixel_data.offset = value;}void NeoPixel_Clear(void) {// Clear bufferfor (uint8_t i = 0; i < NEOPIXEL_LENGTH * 3; i++) {neopixel_data.values[i] = 0x0;}}void NeoPixel_Set(uint8_t index, uint8_t R, uint8_t G, uint8_t B, uint8_t multiplier) {uint8_t i = ((index + neopixel_data.offset) % NEOPIXEL_LENGTH);if (G == 0)neopixel_data.values[(i * 3) + 0] = 0;elseneopixel_data.values[(i * 3) + 0] = (G * multiplier) - 1;if (R == 0)neopixel_data.values[(i * 3) + 1] = 0;elseneopixel_data.values[(i * 3) + 1] = (R * multiplier) - 1;if (B == 0)neopixel_data.values[(i * 3) + 2] = 0;elseneopixel_data.values[(i * 3) + 2] = (B * multiplier) - 1;}void NeoPixel_Or(uint8_t index, uint8_t R, uint8_t G, uint8_t B, uint8_t multiplier) {uint8_t i = ((index + neopixel_data.offset) % NEOPIXEL_LENGTH);if (G != 0)neopixel_data.values[(i * 3) + 0] |= (G * multiplier) - 1;if (R != 0)neopixel_data.values[(i * 3) + 1] |= (R * multiplier) - 1;if (B != 0)neopixel_data.values[(i * 3) + 2] |= (B * multiplier) - 1;}void NeoPixel_Write_All(void) {for (uint8_t i = 0; i < NEOPIXEL_LENGTH * 3; i++) {NeoPixel_Write_One(neopixel_data.values[i]);}// Delay for 50us to latch data__delay_us(50);}void NeoPixel_Write_One(uint8_t value) {// Enable timer and wait for it to overflowT2CONbits.TMR2ON = 1;while (!PIR1bits.TMR2IF);// Set pulse width for bit 7if (value & 0x80) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}while (!PIR1bits.TMR2IF);// Set pulse width for bit 6if (value & 0x40) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}while (!PIR1bits.TMR2IF);// Set pulse width for bit 5if (value & 0x20) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}while (!PIR1bits.TMR2IF);// Set pulse width for bit 4if (value & 0x10) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}while (!PIR1bits.TMR2IF);// Set pulse width for bit 3if (value & 0x08) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}while (!PIR1bits.TMR2IF);// Set pulse width for bit 2if (value & 0x04) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}while (!PIR1bits.TMR2IF);// Set pulse width for bit 1if (value & 0x02) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}while (!PIR1bits.TMR2IF);// Set pulse width for bit 0if (value & 0x01) {CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)} else {CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)}// Idle line lowwhile (!PIR1bits.TMR2IF);asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");CCPR1L = 0b00000000;// Disable and reset timerwhile (!PIR1bits.TMR2IF);asm("NOP");asm("NOP");T2CONbits.TMR2ON = 0;TMR2 = 0x0;}