|
|
@ -16,6 +16,122 @@ |
|
|
|
#include <util/delay.h> |
|
|
|
#include "debug.h" |
|
|
|
|
|
|
|
#define RGBW_BB_TWI 1 |
|
|
|
|
|
|
|
#ifdef RGBW_BB_TWI |
|
|
|
|
|
|
|
// Port for the I2C |
|
|
|
#define I2C_DDR DDRD |
|
|
|
#define I2C_PIN PIND |
|
|
|
#define I2C_PORT PORTD |
|
|
|
|
|
|
|
// Pins to be used in the bit banging |
|
|
|
#define I2C_CLK 0 |
|
|
|
#define I2C_DAT 1 |
|
|
|
|
|
|
|
#define I2C_DATA_HI()\ |
|
|
|
I2C_DDR &= ~ (1 << I2C_DAT);\ |
|
|
|
I2C_PORT |= (1 << I2C_DAT); |
|
|
|
#define I2C_DATA_LO()\ |
|
|
|
I2C_DDR |= (1 << I2C_DAT);\ |
|
|
|
I2C_PORT &= ~ (1 << I2C_DAT); |
|
|
|
|
|
|
|
#define I2C_CLOCK_HI()\ |
|
|
|
I2C_DDR &= ~ (1 << I2C_CLK);\ |
|
|
|
I2C_PORT |= (1 << I2C_CLK); |
|
|
|
#define I2C_CLOCK_LO()\ |
|
|
|
I2C_DDR |= (1 << I2C_CLK);\ |
|
|
|
I2C_PORT &= ~ (1 << I2C_CLK); |
|
|
|
|
|
|
|
#define I2C_DELAY 1 |
|
|
|
|
|
|
|
void I2C_WriteBit(unsigned char c) |
|
|
|
{ |
|
|
|
if (c > 0) |
|
|
|
{ |
|
|
|
I2C_DATA_HI(); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
I2C_DATA_LO(); |
|
|
|
} |
|
|
|
|
|
|
|
I2C_CLOCK_HI(); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
|
|
|
|
I2C_CLOCK_LO(); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
|
|
|
|
if (c > 0) |
|
|
|
{ |
|
|
|
I2C_DATA_LO(); |
|
|
|
} |
|
|
|
|
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
} |
|
|
|
|
|
|
|
// Inits bitbanging port, must be called before using the functions below |
|
|
|
// |
|
|
|
void I2C_Init() |
|
|
|
{ |
|
|
|
I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); |
|
|
|
|
|
|
|
I2C_CLOCK_HI(); |
|
|
|
I2C_DATA_HI(); |
|
|
|
|
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
} |
|
|
|
|
|
|
|
// Send a START Condition |
|
|
|
// |
|
|
|
void I2C_Start() |
|
|
|
{ |
|
|
|
// set both to high at the same time |
|
|
|
I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
|
|
|
|
I2C_DATA_LO(); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
|
|
|
|
I2C_CLOCK_LO(); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
} |
|
|
|
|
|
|
|
// Send a STOP Condition |
|
|
|
// |
|
|
|
void I2C_Stop() |
|
|
|
{ |
|
|
|
I2C_CLOCK_HI(); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
|
|
|
|
I2C_DATA_HI(); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
} |
|
|
|
|
|
|
|
// write a byte to the I2C slave device |
|
|
|
// |
|
|
|
unsigned char I2C_Write(unsigned char c) |
|
|
|
{ |
|
|
|
for (char i = 0; i < 8; i++) |
|
|
|
{ |
|
|
|
I2C_WriteBit(c & 128); |
|
|
|
|
|
|
|
c <<= 1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
I2C_WriteBit(0); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
_delay_us(I2C_DELAY); |
|
|
|
|
|
|
|
// _delay_us(I2C_DELAY); |
|
|
|
//return I2C_ReadBit(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
// Setleds for standard RGB |
|
|
|
void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) |
|
|
|
{ |
|
|
@ -41,6 +157,25 @@ void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) |
|
|
|
_SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); |
|
|
|
|
|
|
|
ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF)); |
|
|
|
|
|
|
|
#ifdef RGBW_BB_TWI |
|
|
|
cli(); |
|
|
|
TWCR = 0; |
|
|
|
I2C_Init(); |
|
|
|
I2C_Start(); |
|
|
|
I2C_Write(0x84); |
|
|
|
uint16_t datlen = leds<<2; |
|
|
|
uint8_t curbyte; |
|
|
|
uint8_t * data = (uint8_t*)ledarray; |
|
|
|
while (datlen--) { |
|
|
|
curbyte=*data++; |
|
|
|
I2C_Write(curbyte % 0x10); |
|
|
|
} |
|
|
|
I2C_Stop(); |
|
|
|
sei(); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
_delay_us(80); |
|
|
|
} |
|
|
|
|
|
|
@ -123,7 +258,7 @@ void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi) |
|
|
|
cli(); |
|
|
|
|
|
|
|
while (datlen--) { |
|
|
|
curbyte=*data++; |
|
|
|
curbyte=(*data++) % 0x10; |
|
|
|
|
|
|
|
asm volatile( |
|
|
|
" ldi %0,8 \n\t" |
|
|
|