aboutsummaryrefslogtreecommitdiff
path: root/quantum/light_ws2812.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/light_ws2812.c')
-rwxr-xr-xquantum/light_ws2812.c151
1 files changed, 146 insertions, 5 deletions
diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c
index 401845e85..a883b1388 100755
--- a/quantum/light_ws2812.c
+++ b/quantum/light_ws2812.c
@@ -16,14 +16,128 @@
16#include <util/delay.h> 16#include <util/delay.h>
17#include "debug.h" 17#include "debug.h"
18 18
19#ifdef RGBW_BB_TWI
20
21// Port for the I2C
22#define I2C_DDR DDRD
23#define I2C_PIN PIND
24#define I2C_PORT PORTD
25
26// Pins to be used in the bit banging
27#define I2C_CLK 0
28#define I2C_DAT 1
29
30#define I2C_DATA_HI()\
31I2C_DDR &= ~ (1 << I2C_DAT);\
32I2C_PORT |= (1 << I2C_DAT);
33#define I2C_DATA_LO()\
34I2C_DDR |= (1 << I2C_DAT);\
35I2C_PORT &= ~ (1 << I2C_DAT);
36
37#define I2C_CLOCK_HI()\
38I2C_DDR &= ~ (1 << I2C_CLK);\
39I2C_PORT |= (1 << I2C_CLK);
40#define I2C_CLOCK_LO()\
41I2C_DDR |= (1 << I2C_CLK);\
42I2C_PORT &= ~ (1 << I2C_CLK);
43
44#define I2C_DELAY 1
45
46void I2C_WriteBit(unsigned char c)
47{
48 if (c > 0)
49 {
50 I2C_DATA_HI();
51 }
52 else
53 {
54 I2C_DATA_LO();
55 }
56
57 I2C_CLOCK_HI();
58 _delay_us(I2C_DELAY);
59
60 I2C_CLOCK_LO();
61 _delay_us(I2C_DELAY);
62
63 if (c > 0)
64 {
65 I2C_DATA_LO();
66 }
67
68 _delay_us(I2C_DELAY);
69}
70
71// Inits bitbanging port, must be called before using the functions below
72//
73void I2C_Init()
74{
75 I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
76
77 I2C_CLOCK_HI();
78 I2C_DATA_HI();
79
80 _delay_us(I2C_DELAY);
81}
82
83// Send a START Condition
84//
85void I2C_Start()
86{
87 // set both to high at the same time
88 I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
89 _delay_us(I2C_DELAY);
90
91 I2C_DATA_LO();
92 _delay_us(I2C_DELAY);
93
94 I2C_CLOCK_LO();
95 _delay_us(I2C_DELAY);
96}
97
98// Send a STOP Condition
99//
100void I2C_Stop()
101{
102 I2C_CLOCK_HI();
103 _delay_us(I2C_DELAY);
104
105 I2C_DATA_HI();
106 _delay_us(I2C_DELAY);
107}
108
109// write a byte to the I2C slave device
110//
111unsigned char I2C_Write(unsigned char c)
112{
113 for (char i = 0; i < 8; i++)
114 {
115 I2C_WriteBit(c & 128);
116
117 c <<= 1;
118 }
119
120
121 I2C_WriteBit(0);
122 _delay_us(I2C_DELAY);
123 _delay_us(I2C_DELAY);
124
125 // _delay_us(I2C_DELAY);
126 //return I2C_ReadBit();
127 return 0;
128}
129
130
131#endif
132
19// Setleds for standard RGB 133// Setleds for standard RGB
20void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) 134void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds)
21{ 135{
22 // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); 136 // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
23 ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF)); 137 ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF));
24} 138}
25 139
26void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask) 140void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask)
27{ 141{
28 // ws2812_DDRREG |= pinmask; // Enable DDR 142 // ws2812_DDRREG |= pinmask; // Enable DDR
29 // new universal format (DDR) 143 // new universal format (DDR)
@@ -34,14 +148,41 @@ void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pin
34} 148}
35 149
36// Setleds for SK6812RGBW 150// Setleds for SK6812RGBW
37void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) 151void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds)
38{ 152{
153
154 #ifdef RGBW_BB_TWI
155 uint8_t sreg_prev, twcr_prev;
156 sreg_prev=SREG;
157 twcr_prev=TWCR;
158 cli();
159 TWCR &= ~(1<<TWEN);
160 I2C_Init();
161 I2C_Start();
162 I2C_Write(0x84);
163 uint16_t datlen = leds<<2;
164 uint8_t curbyte;
165 uint8_t * data = (uint8_t*)ledarray;
166 while (datlen--) {
167 curbyte=*data++;
168 I2C_Write(curbyte);
169 }
170 I2C_Stop();
171 SREG=sreg_prev;
172 TWCR=twcr_prev;
173 #endif
174
175
39 // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR 176 // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
40 // new universal format (DDR) 177 // new universal format (DDR)
41 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); 178 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF);
42 179
43 ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF)); 180 ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
44 _delay_us(80); 181
182
183 #ifndef RGBW_BB_TWI
184 _delay_us(80);
185 #endif
45} 186}
46 187
47void ws2812_sendarray(uint8_t *data,uint16_t datlen) 188void ws2812_sendarray(uint8_t *data,uint16_t datlen)
@@ -123,7 +264,7 @@ void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
123 cli(); 264 cli();
124 265
125 while (datlen--) { 266 while (datlen--) {
126 curbyte=*data++; 267 curbyte=(*data++);
127 268
128 asm volatile( 269 asm volatile(
129 " ldi %0,8 \n\t" 270 " ldi %0,8 \n\t"