Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
280 Kevin 1
#include "defines.h"
2
#include "NEOPIXEL.h"
3
 
281 Kevin 4
extern NEOPIXEL_DATA neopixel_data;
280 Kevin 5
 
281 Kevin 6
void NeoPixel_Init(void) {
280 Kevin 7
 
8
    // Clear buffer
281 Kevin 9
    for (uint8_t i = 0; i < NEOPIXEL_LENGTH * 3; i++) {
10
        neopixel_data.values[i] = 0x0;
280 Kevin 11
    }
12
 
281 Kevin 13
    neopixel_data.offset = 0;
14
 
280 Kevin 15
    // Output pin initially blocked
16
    NEOPIXEL_TRIS = 1;
17
 
18
    /* Initialize PWM module */
19
    PR2 = 0x09; // 1.25us @ 32MHz
20
    CCP1CONbits.P1M = 0b00;     // Single output, P1A modulated only
21
    CCP1CONbits.CCP1M = 0b1100; // PWM mode, P1A active-high, P1B active-high
22
 
23
    // Idle the output till width is specified
24
    CCPR1L = 0x00;
25
    CCP1CONbits.DC1B = 0b00;
26
 
27
    /* Initialize Timer 2 */
28
    PIR1bits.TMR2IF = 0;        // Clear the interrupt flag for Timer 2
29
    T2CONbits.T2CKPS = 0b00;    // Set a prescaler of 1:1
30
    T2CONbits.TMR2ON = 1;       // Enable the timer
31
 
32
    // Wait for the timer to overflow before enabling output
33
    while (!PIR1bits.TMR2IF);
34
    NEOPIXEL_TRIS = 0;
35
}
36
 
281 Kevin 37
void NeoPixel_Offet(uint8_t value) {
38
    neopixel_data.offset = value;
39
}
280 Kevin 40
 
281 Kevin 41
void NeoPixel_Clear(void) {
42
    // Clear buffer
43
    for (uint8_t i = 0; i < NEOPIXEL_LENGTH * 3; i++) {
44
        neopixel_data.values[i] = 0x0;
45
    }
280 Kevin 46
}
47
 
281 Kevin 48
void NeoPixel_Set(uint8_t index, uint8_t R, uint8_t G, uint8_t B) {
49
    uint8_t i = ((index + neopixel_data.offset) % NEOPIXEL_LENGTH);
50
 
51
    neopixel_data.values[(i * 3) + 0] = G;
52
    neopixel_data.values[(i * 3) + 1] = R;
53
    neopixel_data.values[(i * 3) + 2] = B;
54
}
55
 
56
void NeoPixel_Or(uint8_t index, uint8_t R, uint8_t G, uint8_t B) {
57
    uint8_t i = ((index + neopixel_data.offset) % NEOPIXEL_LENGTH);
58
 
59
    neopixel_data.values[(i * 3) + 0] |= G;
60
    neopixel_data.values[(i * 3) + 1] |= R;
61
    neopixel_data.values[(i * 3) + 2] |= B;
62
}
63
 
280 Kevin 64
void NeoPixel_Write_All(void) {
281 Kevin 65
    for (uint8_t i = 0; i < NEOPIXEL_LENGTH * 3; i++) {
66
        NeoPixel_Write_One(neopixel_data.values[i]);
280 Kevin 67
    }
68
    // Delay for 50us to latch data
69
    __delay_us(50);
70
}
71
 
281 Kevin 72
void NeoPixel_Write_One(uint8_t value) {
280 Kevin 73
    // Enable timer and wait for it to overflow
74
    T2CONbits.TMR2ON = 1;
75
    while (!PIR1bits.TMR2IF);
76
 
77
    // Set pulse width for bit 7
78
    if (value & 0x80) {
79
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
80
    } else {
81
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
82
    }
83
    while (!PIR1bits.TMR2IF);
84
 
85
    // Set pulse width for bit 6
86
    if (value & 0x40) {
87
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
88
    } else {
89
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
90
    }
91
    while (!PIR1bits.TMR2IF);
92
 
93
    // Set pulse width for bit 5
94
    if (value & 0x20) {
95
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
96
    } else {
97
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
98
    }
99
    while (!PIR1bits.TMR2IF);
100
 
101
    // Set pulse width for bit 4
102
    if (value & 0x10) {
103
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
104
    } else {
105
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
106
    }
107
    while (!PIR1bits.TMR2IF);
108
 
109
    // Set pulse width for bit 3
110
    if (value & 0x08) {
111
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
112
    } else {
113
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
114
    }
115
    while (!PIR1bits.TMR2IF);
116
 
117
    // Set pulse width for bit 2
118
    if (value & 0x04) {
119
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
120
    } else {
121
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
122
    }
123
    while (!PIR1bits.TMR2IF);
124
 
125
    // Set pulse width for bit 1
126
    if (value & 0x02) {
127
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
128
    } else {
129
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
130
    }
131
    while (!PIR1bits.TMR2IF);
132
 
133
    // Set pulse width for bit 0
134
    if (value & 0x01) {
135
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
136
    } else {
137
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
138
    }
139
 
140
    // Idle line low
141
    while (!PIR1bits.TMR2IF);
142
    asm("NOP");
143
    asm("NOP");
144
    asm("NOP");
145
    asm("NOP");
146
    asm("NOP");
147
    CCPR1L = 0b00000000;
148
 
149
    // Disable and reset timer
150
    while (!PIR1bits.TMR2IF);
151
    asm("NOP");
152
    asm("NOP");
153
    T2CONbits.TMR2ON = 0;
154
    TMR2 = 0x0;
155
}