make led1642 interface more generic

This commit is contained in:
Stefan Rupp 2014-03-18 01:04:18 +01:00
parent 3f424f88a9
commit f2a4bb877c
5 changed files with 228 additions and 124 deletions

View File

@ -1,5 +1,5 @@
PRG = rgbyteclock PRG = rgbyteclock
OBJ = rgbyteclock.o timer.o lcd.o main.o rtc.o spi.o ringbuffer.o crc.o ledcontroller.o OBJ = rgbyteclock.o timer.o lcd.o main.o rtc.o spi.o ringbuffer.o crc.o ledcontroller.o led1642gw.o
MCU_TARGET = atmega164a MCU_TARGET = atmega164a
OPTIMIZE = -Os OPTIMIZE = -Os
@ -27,6 +27,8 @@ $(PRG).elf: $(OBJ)
# dependency: # dependency:
rgbyteclock.o: timer.o lcd.o rgbyteclock.h rtc.o spi.o ledcontroller.o rgbyteclock.o: timer.o lcd.o rgbyteclock.h rtc.o spi.o ledcontroller.o
main.o: rgbyteclock.o lcd.o spi.o ledcontroller.o rtc.o timer.o main.o: rgbyteclock.o lcd.o spi.o ledcontroller.o rtc.o timer.o
ledcontroller.o: led1642gw.o
led1642gw.o: led1642gw.h
timer.o: timer.h timer.o: timer.h
lcd.o: lcd.h timer.o lcd.o: lcd.h timer.o
rtc.o: rtc.h rtc.o: rtc.h

173
led1642gw.c Normal file
View File

@ -0,0 +1,173 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <struppi@struppi.name> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* (c) 2014 Stefan Rupp
* ----------------------------------------------------------------------------
*/
#include <string.h>
#include "led1642gw.h"
#include <util/delay.h>
#define NUM_LED1642GW_CHANNELS (16)
#define NUM_LED_CHANNELS (NUM_LED1642GW_CHANNELS*NUM_LED1642GW_ICs)
#define NUM_LED1642GW_ICs (3)
static uint16_t ledbuffer[NUM_LED_CHANNELS];
#define DDR_CLK (DDRC)
#define PORT_CLK (PORTC)
#define PIN_CLK (3)
#define SET_CLK_H() ((PORT_CLK) |= (1<<(PIN_CLK)))
#define SET_CLK_L() ((PORT_CLK) &= ~(1<<(PIN_CLK)))
#define DDR_SDI (DDRC)
#define PORT_SDI (PORTC)
#define PIN_SDI (4)
#define SET_SDI_H() ((PORT_SDI) |= (1<<(PIN_SDI)))
#define SET_SDI_L() ((PORT_SDI) &= ~(1<<(PIN_SDI)))
#define DDR_LE (DDRC)
#define PORT_LE (PORTC)
#define PIN_LE (2)
#define SET_LE_H() ((PORT_LE) |= (1<<(PIN_LE)))
#define SET_LE_L() ((PORT_LE) &= ~(1<<(PIN_LE)))
static void write_data(uint16_t data, uint8_t le_clocks)
{
uint16_t mask = 0x8000;
int8_t bit;
//PORTC &= ~(1<<PC2);
SET_LE_L();
for (bit=15; bit>=le_clocks; bit--) {
//PORTC &= ~(1<<PC3);
SET_CLK_L();
if(data&mask) { SET_SDI_H(); }
else { SET_SDI_L(); }
//PORTC |= (1<<PC3);
SET_CLK_H();
mask >>= 1;
}
//PORTC |= (1<<PC2);
SET_LE_H();
for (/*noting to initialize*/; bit>=0; bit--) {
//PORTC &= ~(1<<PC3);
SET_CLK_L();
if(data&mask) { SET_SDI_H(); }
else { SET_SDI_L(); }
//PORTC |= (1<<PC3);
SET_CLK_H();
mask >>= 1;
}
//PORTC &= ~(1<<PC3);
SET_CLK_L();
//PORTC &= ~(1<<PC2);
SET_LE_L();
//PORTC &= ~(1<<PC4);
SET_SDI_L();
}
static void write_data_latch(uint16_t data)
{
write_data(data, 4);
}
static void write_global_latch(uint16_t data)
{
write_data(data, 6);
}
static void write_no_command(uint16_t data)
{
write_data(data, 0);
}
void led1642gw_turn_all_on(void)
{
write_data(0xffff, 2);
_delay_us(10);
write_data(0xffff, 2);
_delay_us(10);
write_data(0xffff, 2);
_delay_us(10);
}
void led1642gw_turn_all_off(void)
{
write_data(0x0000, 2);
_delay_us(10);
write_data(0x0000, 2);
_delay_us(10);
write_data(0x0000, 2);
_delay_us(10);
}
void led1642gw_init(void)
{
//PORTC &= ~(1<<PC3); // SCK
SET_CLK_L();
//PORTC &= ~(1<<PC4); // DATA
SET_SDI_L();
//PORTC &= ~(1<<PC2); // LE
SET_LE_L();
//DDRC |= (1<<PC3); // SCK
DDR_CLK |= (1<<PIN_CLK);
//DDRC |= (1<<PC4); // DATA
DDR_SDI |= (1<<PIN_SDI);
//DDRC |= (1<<PC2); // LE
DDR_LE |= (1<<PIN_LE);
memset(ledbuffer, 0x00, sizeof(ledbuffer));
led1642gw_flush();
}
void led1642gw_flush(void)
{
uint8_t channel;
uint8_t ic;
for (channel=0; channel<NUM_LED1642GW_CHANNELS-1; channel++) {
for (ic=0; ic<(NUM_LED1642GW_ICs-1); ic++) {
write_no_command(ledbuffer[channel+(NUM_LED1642GW_CHANNELS*ic)]);
}
write_data_latch(ledbuffer[channel+(ic*NUM_LED1642GW_CHANNELS)]);
}
for (ic=1; ic<NUM_LED1642GW_ICs; ic++) {
write_no_command(ledbuffer[(ic*NUM_LED1642GW_CHANNELS)-1]);
}
write_global_latch(ledbuffer[(ic*NUM_LED1642GW_CHANNELS)-1]);
}
void led1642gw_set_channel(uint8_t channel, uint16_t value)
{
if (channel < NUM_LED_CHANNELS) {
ledbuffer[channel] = value;
}
}
void led1642gw_clear(void)
{
memset(ledbuffer, 0x00, sizeof(ledbuffer));
}

28
led1642gw.h Normal file
View File

@ -0,0 +1,28 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <struppi@struppi.name> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* (c) 2014 Stefan Rupp
* ----------------------------------------------------------------------------
*/
#ifndef LED1642GW_H_
#define LED1642GW_H_
#include <avr/io.h>
#include <stdint.h>
void led1642gw_init(void);
void led1642gw_turn_all_on(void);
void led1642gw_turn_all_off(void);
void led1642gw_flush(void);
void led1642gw_set_channel(uint8_t channel, uint16_t value);
void led1642gw_clear(void);
#endif // LED1642GW_H_

View File

@ -17,16 +17,9 @@
*/ */
#include "ledcontroller.h" #include "ledcontroller.h"
#include <string.h> #include "led1642gw.h"
#include <util/delay.h>
#define NUM_LED1642GW_ICs (3)
#define NUM_LED1642GW_CHANNELS (16)
#define NUM_LED_CHANNELS (NUM_LED1642GW_CHANNELS*NUM_LED1642GW_ICs)
static uint16_t ledbuffer[NUM_LED_CHANNELS];
static int8_t map_lednum_to_channels(uint8_t lednum, uint8_t *channel_r, uint8_t *channel_g, uint8_t *channel_b) static int8_t map_lednum_to_channels(uint8_t lednum, uint8_t *channel_r, uint8_t *channel_g, uint8_t *channel_b)
{ {
uint8_t ret=0; uint8_t ret=0;
@ -115,125 +108,38 @@ static int8_t map_lednum_to_channels(uint8_t lednum, uint8_t *channel_r, uint8_t
} }
static void write_data(uint16_t data, uint8_t le_clocks)
{
uint16_t mask = 0x8000;
int8_t bit;
PORTC &= ~(1<<PC2);
for (bit=15; bit>=le_clocks; bit--) {
PORTC &= ~(1<<PC3);
if(data&mask) { PORTC |= (1<<PC4); }
else { PORTC &= ~(1<<PC4); }
PORTC |= (1<<PC3);
mask >>= 1;
}
PORTC |= (1<<PC2);
for (/*noting to initialize*/; bit>=0; bit--) {
PORTC &= ~(1<<PC3);
if(data&mask) { PORTC |= (1<<PC4); }
else { PORTC &= ~(1<<PC4); }
PORTC |= (1<<PC3);
mask >>= 1;
}
PORTC &= ~(1<<PC3);
PORTC &= ~(1<<PC2);
PORTC &= ~(1<<PC4);
}
static void write_data_latch(uint16_t data)
{
write_data(data, 4);
}
static void write_global_latch(uint16_t data)
{
write_data(data, 6);
}
static void write_no_command(uint16_t data)
{
write_data(data, 0);
}
void led_turn_all_on(void)
{
write_data(0xffff, 2);
_delay_us(10);
write_data(0xffff, 2);
_delay_us(10);
write_data(0xffff, 2);
_delay_us(10);
}
void led_turn_all_off(void)
{
write_data(0x0000, 2);
_delay_us(10);
write_data(0x0000, 2);
_delay_us(10);
write_data(0x0000, 2);
_delay_us(10);
}
void led_init(void)
{
PORTC &= ~(1<<PC3); // SCK
PORTC &= ~(1<<PC4); // DATA
PORTC &= ~(1<<PC2); // LE
DDRC |= (1<<PC3); // SCK
DDRC |= (1<<PC4); // DATA
DDRC |= (1<<PC2); // LE
memset(ledbuffer, 0x00, sizeof(ledbuffer));
led_flush();
}
void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue) void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue)
{ {
uint8_t c_r, c_g, c_b; uint8_t c_r, c_g, c_b;
if ( map_lednum_to_channels(lednum, &c_r, &c_g, &c_b) > 0 ) { if ( map_lednum_to_channels(lednum, &c_r, &c_g, &c_b) > 0 ) {
ledbuffer[c_r] = red; led1642gw_set_channel(c_r, red);
ledbuffer[c_g] = green; led1642gw_set_channel(c_g, green);
ledbuffer[c_b] = blue; led1642gw_set_channel(c_b, blue);
} }
}
}
void led_flush(void) void led_flush(void)
{ {
uint8_t channel; led1642gw_flush();
for (channel=0; channel<NUM_LED1642GW_CHANNELS-1; channel++) {
write_no_command(ledbuffer[channel+0]);
write_no_command(ledbuffer[channel+NUM_LED1642GW_CHANNELS]);
write_data_latch(ledbuffer[channel+(2*NUM_LED1642GW_CHANNELS)]);
}
write_no_command(ledbuffer[NUM_LED1642GW_CHANNELS-1]);
write_no_command(ledbuffer[(2*NUM_LED1642GW_CHANNELS)-1]);
write_global_latch(ledbuffer[(3*NUM_LED1642GW_CHANNELS)-1]);
}
void led_set_channel(uint8_t channel, uint16_t value)
{
if (channel < NUM_LED_CHANNELS) {
ledbuffer[channel] = value;
}
} }
void led_clear(void) void led_clear(void)
{ {
memset(ledbuffer, 0x00, sizeof(ledbuffer)); led1642gw_clear();
} }
void led_init(void)
{
led1642gw_init();
}
void led_turn_all_on(void)
{
led1642gw_turn_all_on();
}

View File

@ -14,18 +14,13 @@
#define LEDCONTROLLER_H #define LEDCONTROLLER_H
#include <avr/io.h> #include <avr/io.h>
#include <compat/ina90.h> // ==> _NOP()
#include "timer.h" #include "timer.h"
void led_init(void); void led_init(void);
void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue); void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue);
void led_flush(void); void led_flush(void);
void led_turn_all_on(void);
void led_turn_all_off(void);
void led_set_channel(uint8_t channel, uint16_t value);
void led_clear(void); void led_clear(void);
void led_turn_all_on(void);
#endif // LEDCONTROLLER_H #endif // LEDCONTROLLER_H