-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsk9822.c
305 lines (288 loc) · 7.94 KB
/
sk9822.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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/**
****************************************************************
@file sk9822.c
****************************************************************
@brief driver for the SK9822 LED-Strip
****************************************************************
@author Edwin Koch
@version 1.0
@date 2019-10-22
******************************************************************/
#include "sk9822.h"
#include <stdint.h>
#include <stdbool.h>
static fptr_U8_t spi_tx = NULL_POINTER;
static led_color_t led_strip_buff[N_LED]; //!< LED buffer init
/*
****************************************************************
@brief start sequence for addressing SK9822 LEDs. See datasheet
for more information.
@param -
@return -
****************************************************************
*/
void _start_sequence()
{
spi_tx(0x00);
spi_tx(0x00);
spi_tx(0x00);
spi_tx(0x00);
}
/*
****************************************************************
@brief stop sequence for addressing SK9822 LEDs. See datasheet
for more information.
@param -
@return -
****************************************************************
*/
void _stop_sequence()
{
spi_tx(0xFF);
spi_tx(0xFF);
spi_tx(0xFF);
spi_tx(0xFF);
}
/*
****************************************************************
@brief writes the entire LED settings buffer to the LEDs.
@param -
@return -
****************************************************************
*/
void _writeLEDs()
{
uint8_t i = 0;
_start_sequence();
for(i = 0; i < N_LED ; i++) {
spi_tx(led_strip_buff[i].brightness | 0xE0);
spi_tx(led_strip_buff[i].blue);
spi_tx(led_strip_buff[i].green);
spi_tx(led_strip_buff[i].red);
}
_stop_sequence();
}
/*
****************************************************************
@brief shifts all LEDs once in the desired direction determined
by dir.
Data shifted over border is lost!
@param dir true: right , false: left
@bug
@return -
****************************************************************
*/
void _shift_all_once(bool dir)
{
uint8_t i = 0;
led_color_t zero={
.brightness = 0,
.red = 0,
.green = 0,
.blue = 0
};
if(dir){
for(i = (N_LED - 1); i > 0; i--){
led_strip_buff[i] = led_strip_buff[i-1];
}
led_strip_buff[0] = zero;
}else{
for(i = 0; i < (N_LED - 1); i++){
led_strip_buff[i] = led_strip_buff[i+1];
}
led_strip_buff[N_LED - 1] = zero;
}
}
/*
****************************************************************
@brief ring shifts all LEDs once in the desired direction determined
by dir.
Data shifted over border is attached on the opposite border!
@param dir true: right , false: left
@return -
****************************************************************
*/
void _ringshift_all_once(bool dir)
{
uint8_t i = 0;
led_color_t buff;
if(dir){
buff = led_strip_buff[N_LED - 1];
for(i = (N_LED - 1); i > 0; i--){
led_strip_buff[i] = led_strip_buff[i-1];
}
led_strip_buff[0] = buff;
}else{
buff = led_strip_buff[0];
for(i = 0; i < (N_LED - 1); i++){
led_strip_buff[i] = led_strip_buff[i+1];
}
led_strip_buff[N_LED - 1] = buff;
}
}
/*
****************************************************************
@brief initializes the ledstrip driver
the spi init function is called here and the callbacks
for chipselect and for the spi transmission are
implemented
@param spi_init spi init function pointer
@param spi_transmit spi transmit function pointer
@param chipselect function containing containing the gpio related
actions to select/deselect the ledstrip
@return -
****************************************************************
*/
void sk9822_init(fptr_U8_t spi_transmit)
{
spi_tx = spi_transmit;
}
/*
****************************************************************
@brief updates one LEDs color
The buffer is updated and all its content is written to the strip
@param n_led led number
@param color color_t
@return -
****************************************************************
*/
void sk9822_set_LED_color(uint8_t n_led,led_color_t color)
{
if(n_led > N_LED) return;
color.brightness |= 0xE0;
led_strip_buff[n_led] = color;
_writeLEDs();
}
/*
****************************************************************
@brief updates rgb of one LED
The buffer is updated and all its content is written to the strip
@param n_led led number
@param r red
@param g green
@param b blue
@return -
****************************************************************
*/
void sk9822_set_LED_rgb(uint8_t n_led,uint8_t level, uint8_t r, uint8_t g, uint8_t b)
{
led_color_t color = {
.brightness = level | 0xE0,
.red = r,
.green = g,
.blue = b,
};
ledstrip_set_LED_color(n_led, color);
}
/*
****************************************************************
@brief updates all LED color
The buffer is updated and all its content is written to the strip
@param color color_t
@return -
****************************************************************
*/
void sk9822_set_color_all(led_color_t color)
{
uint8_t i = 0;
_start_sequence();
for(i = 0; i < N_LED ; i++) {
led_strip_buff[i] = color;
spi_tx(led_strip_buff[i].brightness);
spi_tx(led_strip_buff[i].blue);
spi_tx(led_strip_buff[i].green);
spi_tx(led_strip_buff[i].red);
}
_stop_sequence();
}
void sk9822_set_rgb_all(uint8_t level, uint8_t r, uint8_t g, uint8_t b)
{
led_color_t color = {
.brightness = level | 0xE0,
.red = r,
.green = g,
.blue = b
};
ledstrip_set_color_all(color);
}
/*
****************************************************************
@brief updates one LEDs color
The buffer is updated but its content is only written to the strip
when ledstrip_update_all() is called.
@param n_led led number
@param color color_t
@return -
****************************************************************
*/
void sk9822_pending_set_LED_color(uint8_t led_n, led_color_t color)
{
if(led_n > N_LED) return;
color.brightness |= 0xE0;
led_strip_buff[led_n] = color;
}
/*
****************************************************************
@brief updates rgb of one LED
The buffer is updated but its content is only written to the strip
when ledstrip_update_all() is called.
@param n_led led number
@param r red
@param g green
@param b blue
@return -
****************************************************************
*/
void sk9822_pending_set_LED_rgb(uint8_t led_n, uint8_t level, uint8_t r, uint8_t g, uint8_t b)
{
if(led_n > N_LED) return;
led_strip_buff[led_n].brightness = level | 0xE0;
led_strip_buff[led_n].blue = b;
led_strip_buff[led_n].red = r;
led_strip_buff[led_n].green = g;
}
/*
****************************************************************
@brief updates all LEDs with the buffer content
All settings made in the buffer by the pending functions
are written to the LEDs.
@param -
@return -
****************************************************************
*/
void sk9822_update_all()
{
_writeLEDs();
}
/*
****************************************************************
@brief Shift all LED settings n positions in direction
determined by dir.
Data pushed over the border is lost!
@param dir true : Right , false : left
@param n_position shift n positions in direction determined by dir
@return -
****************************************************************
*/
void sk9822_shift_all(bool dir,uint8_t n_position)
{
uint8_t i = 0;
for(i = 0; i<n_position;i++)_shift_all_once(dir);
_writeLEDs();
}
/*
****************************************************************
@brief ring shift all LED settings n positions in direction
determined by dir.
Data pushed over the border is attached to the opposite border.
@param dir true : Right , false : left
@param n_position shift n positions in direction determined by dir
@return -
****************************************************************
*/
void sk9822_ring_shift_all(bool dir,uint8_t n_position)
{
uint8_t i = 0;
for(i = 0; i<n_position;i++)_ringshift_all_once(dir);
_writeLEDs();
}