-
Notifications
You must be signed in to change notification settings - Fork 0
/
replacing.c
188 lines (151 loc) · 4.21 KB
/
replacing.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//Raycon light strip sgv May2013
typedef volatile unsigned int ioreg;
#define PIO_PER (ioreg *) 0xfffff400 // PIO Enable Register
#define PIO_OER (ioreg *) 0xfffff410 // Output Enable Register
#define PIO_SODR (ioreg *) 0xfffff430 // Set Output Data Register
#define PIO_IFER (ioreg *) 0xfffff420 // Input Glitch Filter Enable Register
#define PIO_CODR (ioreg *) 0xfffff434 // Clear Output Data Register
#define PIO_PPUDR (ioreg *) 0xfffff460 // Pullup Disable Register
#define PIO_PDSR (ioreg *) 0xfffff43c // Pin Data Status Register
#define PMC_PCER (ioreg *) 0xfffffc10 // Peripheral Clock Enable Register
#define CK1 0x00000002
#define SD1 0x00000001
#define PIOA_IDENTIFIER 0x00000004// Bit 2 of register - corresponds to peripheral identifier no. 2
// i.e. the peripheral identifier for parallel i/o interface A
#define DELAY 0x00500000 //
#define STEP_DELAY 0x00010000 //
#define OUTPUTS CK1|SD1
#define STRIP_SIZE 32
#define LBUFSIZE (STRIP_SIZE * 3)
#define DIVIDER 0xf
typedef unsigned char bool;
#define true ((bool)1)
#define false ((bool)0)
char lbuf[ LBUFSIZE ];
void delay(unsigned int count);
void white();
void byte();
void byte2();
void clear();
void * memcpy(void * restrict destination, void const * restrict source, unsigned int num);
void lupdate(void);
void lcopy(void);
typedef struct triad {
unsigned char red;
unsigned char green;
unsigned char blue;
} triad_t;
bool triad_equal(triad_t const * left, triad_t const * right)
{
return left->red == right->red &&
left->green == right->green &&
left->blue == right->blue;
}
triad_t strip[ STRIP_SIZE ];
triad_t buffer[ STRIP_SIZE ];
#define RED ((triad_t){ 128, 0, 0 })
#define BLUE ((triad_t){ 0, 0, 128 })
#define GREEN ((triad_t){ 0, 128, 0 })
#define MAGENTA ((triad_t){ 128, 0, 128 })
#define YELLOW ((triad_t){ 128, 128, 0 })
#define CYAN ((triad_t){ 0, 128, 128 })
bool check_pattern(unsigned int i, triad_t left, triad_t middle, triad_t right)
{
return triad_equal(&strip[i-1], &left) &&
triad_equal(&strip[i], &middle) &&
triad_equal(&strip[i+1], &right);
}
int main(void)
{
*PIO_PER = OUTPUTS; // Enable control of I/O pins from PIO Controller
*PIO_OER = OUTPUTS; // Enable output drivers for relevant pins
*PMC_PCER = PIOA_IDENTIFIER;
*PIO_CODR = CK1;
for (unsigned int i = 0; i != STRIP_SIZE; i++)
strip[ i ] = RED;
//for (i = 0; i < LBUFSIZE; i++)
// lbuf[ i ] = 0;
delay(16 * 1000);
for (unsigned int loopy = 0; ; loopy++)
{
// Copy buffer to be worked on
memcpy(buffer, strip, sizeof(strip));
// Work out the next value for each of the LEDs
for (unsigned int current = 1; current != (STRIP_SIZE - 1); ++current)
{
if (check_pattern(current, RED, RED, RED))
{
buffer[current] = GREEN;
break;
}
else if (check_pattern(current, RED, GREEN, RED))
{
buffer[current] = BLUE;
}
else if (check_pattern(current, BLUE, RED, GREEN))
{
buffer[current] = CYAN;
}
else if (check_pattern(current, BLUE, CYAN, BLUE))
{
buffer[current-1] = MAGENTA;
}
else if (check_pattern(current, CYAN, MAGENTA, CYAN))
{
buffer[current-1] = GREEN;
}
}
// Copy the buffer back to be rendered
memcpy(strip, buffer, sizeof(buffer));
lcopy();
lupdate();
delay(16 * 1000 * 100); // delay 16,000 clock cycles - long pulse - ~0.5ms - will go down to 3000
}
}
void * memcpy(void * restrict destination, void const * restrict source, unsigned int count)
{
char * restrict dst8 = (char * restrict)destination;
char const * restrict src8 = (char const * restrict)source;
while (count--)
{
*dst8++ = *src8++;
}
return destination;
}
void delay(unsigned int count)
{
volatile unsigned int i;
for (i = count; i != 0; i--);
}
void lupdate(void)
{
for (unsigned int i = 0; i != LBUFSIZE; i++)
{
for (int j = 7; j >= 0; j--)
{
if (lbuf[ i ] & (1 << j))
{
*PIO_CODR=SD1;
*PIO_CODR=CK1;
*PIO_SODR=SD1;
*PIO_SODR=CK1;
}
else
{
*PIO_SODR=SD1;
*PIO_CODR=CK1;
*PIO_SODR=SD1;
*PIO_SODR=CK1;
}
}
}
}
void lcopy(void)
{
for (unsigned int i = 0; i != STRIP_SIZE; i++)
{
lbuf[ i * 3 ] = strip[ i ].red;
lbuf[ i * 3 + 1 ] = strip[ i ].green;
lbuf[ i * 3 + 2 ] = strip[ i ].blue;
}
}