Subversion Repositories Code-Repo

Rev

Rev 279 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
279 Kevin 1
#include <xc.h>
2
#include "defines.h"
3
#include "NEOPIXEL.h"
4
 
5
static NEOPIXEL_DATA* neopixel_data_ptr;
6
 
7
void NeoPixel_Init(NEOPIXEL_DATA *data) {
8
    neopixel_data_ptr = data;
9
 
10
    // Clear buffer
11
    for (char i = 0; i < NEOPIXEL_LENGTH * 3; i++) {
12
        neopixel_data_ptr->values[i] = 0x0;
13
    }
14
 
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
 
37
void NeoPixel_Set(char index, char R, char G, char B) {
38
    if (index >= NEOPIXEL_LENGTH) return;
39
 
40
    neopixel_data_ptr->values[(index * 3) + 0] = G;
41
    neopixel_data_ptr->values[(index * 3) + 1] = R;
42
    neopixel_data_ptr->values[(index * 3) + 2] = B;
43
}
44
 
45
void NeoPixel_Write_All(void) {
46
    for (char i = 0; i < NEOPIXEL_LENGTH * 3; i++) {
47
        NeoPixel_Write_One(neopixel_data_ptr->values[i]);
48
    }
49
    // Delay for 50us to latch data
50
    __delay_us(50);
51
}
52
 
53
void NeoPixel_Write_One(char value) {
54
    // Enable timer and wait for it to overflow
55
    T2CONbits.TMR2ON = 1;
56
    while (!PIR1bits.TMR2IF);
57
 
58
    // Set pulse width for bit 7
59
    if (value & 0x80) {
60
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
61
    } else {
62
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
63
    }
64
    while (!PIR1bits.TMR2IF);
65
 
66
    // Set pulse width for bit 6
67
    if (value & 0x40) {
68
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
69
    } else {
70
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
71
    }
72
    while (!PIR1bits.TMR2IF);
73
 
74
    // Set pulse width for bit 5
75
    if (value & 0x20) {
76
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
77
    } else {
78
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
79
    }
80
    while (!PIR1bits.TMR2IF);
81
 
82
    // Set pulse width for bit 4
83
    if (value & 0x10) {
84
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
85
    } else {
86
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
87
    }
88
    while (!PIR1bits.TMR2IF);
89
 
90
    // Set pulse width for bit 3
91
    if (value & 0x08) {
92
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
93
    } else {
94
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
95
    }
96
    while (!PIR1bits.TMR2IF);
97
 
98
    // Set pulse width for bit 2
99
    if (value & 0x04) {
100
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
101
    } else {
102
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
103
    }
104
    while (!PIR1bits.TMR2IF);
105
 
106
    // Set pulse width for bit 1
107
    if (value & 0x02) {
108
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
109
    } else {
110
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
111
    }
112
    while (!PIR1bits.TMR2IF);
113
 
114
    // Set pulse width for bit 0
115
    if (value & 0x01) {
116
        CCPR1L = NEOPIXEL_LOGIC_1; // ~800ns high, ~450ns low (logic 1)
117
    } else {
118
        CCPR1L = NEOPIXEL_LOGIC_0; // ~400ns high, ~850ns low (logic 0)
119
    }
120
 
121
    // Idle line low
122
    while (!PIR1bits.TMR2IF);
123
    asm("NOP");
124
    asm("NOP");
125
    asm("NOP");
126
    asm("NOP");
127
    asm("NOP");
128
    CCPR1L = 0b00000000;
129
 
130
    // Disable and reset timer
131
    while (!PIR1bits.TMR2IF);
132
    asm("NOP");
133
    asm("NOP");
134
    T2CONbits.TMR2ON = 0;
135
    TMR2 = 0x0;
136
}