159 lines
3.1 KiB
C
159 lines
3.1 KiB
C
|
|
||
|
|
||
|
/*
|
||
|
* ----------------------------------------------------------------------------
|
||
|
* "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;
|
||
|
SET_LE_L();
|
||
|
for (bit=15; bit>=le_clocks; bit--) {
|
||
|
SET_CLK_L();
|
||
|
if(data&mask) { SET_SDI_H(); }
|
||
|
else { SET_SDI_L(); }
|
||
|
SET_CLK_H();
|
||
|
mask >>= 1;
|
||
|
}
|
||
|
|
||
|
SET_LE_H();
|
||
|
for (/*noting to initialize*/; bit>=0; bit--) {
|
||
|
SET_CLK_L();
|
||
|
if(data&mask) { SET_SDI_H(); }
|
||
|
else { SET_SDI_L(); }
|
||
|
SET_CLK_H();
|
||
|
mask >>= 1;
|
||
|
}
|
||
|
|
||
|
SET_CLK_L();
|
||
|
SET_LE_L();
|
||
|
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)
|
||
|
{
|
||
|
|
||
|
SET_CLK_L();
|
||
|
SET_SDI_L();
|
||
|
SET_LE_L();
|
||
|
DDR_CLK |= (1<<PIN_CLK);
|
||
|
DDR_SDI |= (1<<PIN_SDI);
|
||
|
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));
|
||
|
}
|
||
|
|