some improvements

This commit is contained in:
Hans-Gert Dahmen 2011-12-21 06:47:22 +00:00
parent 6325170d1c
commit eaa7b8d715
1 changed files with 51 additions and 25 deletions

View File

@ -19,17 +19,17 @@
#define TLC_PIN_DCPRG 4 #define TLC_PIN_DCPRG 4
#define TLC_PIN_XERR 6 #define TLC_PIN_XERR 6
#define COLDDR DDR(COLPORT) #define COLDDR DDR(TLCPORT)
#define ROWDDR DDR(ROWPORT) #define ROWDDR DDR(ROWPORT)
#define SCLK() { \ #define SCLK() { \
COLPORT |= _BV(TLC_PIN_SCLK); \ TLCPORT |= _BV(TLC_PIN_SCLK); \
COLPORT &= ~_BV(TLC_PIN_SCLK); \ TLCPORT &= ~_BV(TLC_PIN_SCLK); \
} }
#define XLAT() { \ #define XLAT() { \
COLPORT |= _BV(TLC_PIN_XLAT); \ TLCPORT |= _BV(TLC_PIN_XLAT); \
COLPORT &= ~_BV(TLC_PIN_XLAT); \ TLCPORT &= ~_BV(TLC_PIN_XLAT); \
} }
/* more ifdef magic :-( */ /* more ifdef magic :-( */
@ -46,9 +46,6 @@ static void nextrow(uint8_t row) {
unsigned char i; unsigned char i;
static unsigned char row = 0; static unsigned char row = 0;
//blank outputs of low-side (column) driver
COLPORT |= _BV(TLC_PIN_BLANK);
//increment & wrap row counter //increment & wrap row counter
if (++row == NUM_ROWS) row = 0; if (++row == NUM_ROWS) row = 0;
@ -101,15 +98,15 @@ static void rowshow(unsigned char row, unsigned char plane) {
tmp = (tmp >> 4) | (tmp << 4); tmp = (tmp >> 4) | (tmp << 4);
tmp = ((tmp & 0xcc) >> 2) | ((tmp & 0x33)<< 2); //0xcc = 11001100, 0x33 = 00110011 tmp = ((tmp & 0xcc) >> 2) | ((tmp & 0x33)<< 2); //0xcc = 11001100, 0x33 = 00110011
tmp = ((tmp & 0xaa) >> 1) | ((tmp & 0x55)<< 1); //0xaa = 10101010, 0x55 = 1010101 tmp = ((tmp & 0xaa) >> 1) | ((tmp & 0x55)<< 1); //0xaa = 10101010, 0x55 = 1010101
COLPORT2 = tmp; TLCPORT2 = tmp;
tmp = tmp1; tmp = tmp1;
tmp = (tmp >> 4) | (tmp << 4); tmp = (tmp >> 4) | (tmp << 4);
tmp = ((tmp & 0xcc) >> 2) | ((tmp & 0x33) << 2); //0xcc = 11001100, 0x33 = 00110011 tmp = ((tmp & 0xcc) >> 2) | ((tmp & 0x33) << 2); //0xcc = 11001100, 0x33 = 00110011
tmp = ((tmp & 0xaa) >> 1) | ((tmp & 0x55) << 1); //0xaa = 10101010, 0x55 = 1010101 tmp = ((tmp & 0xaa) >> 1) | ((tmp & 0x55) << 1); //0xaa = 10101010, 0x55 = 1010101
COLPORT1 = tmp; TLCPORT1 = tmp;
#else #else
COLPORT1 = tmp; TLCPORT1 = tmp;
COLPORT2 = tmp1; TLCPORT2 = tmp1;
#endif #endif
} }
*/ */
@ -117,12 +114,21 @@ static void rowshow(unsigned char row, unsigned char plane) {
// depending on the plane this interrupt triggers at 50 kHz, 31.25 kHz or // depending on the plane this interrupt triggers at 50 kHz, 31.25 kHz or
// 12.5 kHz // 12.5 kHz
SIGNAL(SIG_OUTPUT_COMPARE0) { ISR(TIMER0_COMP_vect ) {
uint8_t i, x; uint8_t i, x;
// reset watchdog // reset watchdog
wdt_reset(); wdt_reset();
//sync to timer 1
while(!(TIFR1 & _BV(OCF1A)));
//blank outputs of low-side (column) driver
TLCPORT |= _BV(TLC_PIN_BLANK);
//disable timer 1
TCCR1B &= ~_BV(CS10);
// switch rows // switch rows
nextrow(row); nextrow(row);
@ -135,22 +141,33 @@ SIGNAL(SIG_OUTPUT_COMPARE0) {
//shift in 12 bit words //shift in 12 bit words
for(x = 0; x < 12; x++) for(x = 0; x < 12; x++)
{ {
COLPORT &= ~_BV(TLC_PIN_SIN); TLCPORT &= ~_BV(TLC_PIN_SIN);
COLPORT |= ((uint8_t)((uint16_t)0xFFF >> x) & 1) << TLC_PIN_SIN; TLCPORT |= ((uint8_t)((uint16_t)0xFFF >> x) & 1) << TLC_PIN_SIN;
SCLK(); SCLK();
} }
} }
//latch data and disable blanking //latch data, disable blanking, enable and reset timers
XLAT(); XLAT();
COLPORT &= ~_BV(TLC_PIN_BLANK); TCNT1 = 0;
TIFR1 = _BV(OCF1A)
TLCPORT &= ~_BV(TLC_PIN_BLANK);
TCNT0 = 0; //be a little faster than timer 1
TCCR1B |= _BV(CS10); // clk/1
}
ISR(TIMER1_COMPA_vect)
{
TLCPORT |= _BV(TLC_PIN_BLANK);
TLCPORT &= ~_BV(TLC_PIN_BLANK);
} }
void timer0_off() { void timer0_off() {
cli(); cli();
COLPORT = 0; TLCPORT = 0;
ROWPORT = 0; ROWPORT = 0;
#ifdef __AVR_ATmega644P__ #ifdef __AVR_ATmega644P__
@ -160,11 +177,14 @@ void timer0_off() {
TCCR0 = 0x00; TCCR0 = 0x00;
#endif #endif
//disable timer 1 also
TCCR1B &= ~_BV(CS10);
sei(); sei();
} }
// initialize timer which triggers the interrupt // initialize timers which trigger the interrupts
static void timer0_on() { static void timer0_on() {
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 /* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
* CS02 CS01 CS00 * CS02 CS01 CS00
@ -180,14 +200,20 @@ static void timer0_on() {
TCCR0A = 0x02; // CTC Mode TCCR0A = 0x02; // CTC Mode
TCCR0B = 0x04; // clk/256 TCCR0B = 0x04; // clk/256
TCNT0 = 0; // reset timer TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value OCR0 = 0xFF; // compare with this value
TIMSK0 = 0x02; // compare match Interrupt on TIMSK0 = 0x02; // compare match Interrupt on
#else #else
TCCR0 = 0x0C; // CTC Mode, clk/256 TCCR0 = 0x0C; // CTC Mode, clk/256
TCNT0 = 0; // reset timer TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value OCR0 = 0xFF; // compare with this value
TIMSK = 0x02; // compare match Interrupt on TIMSK = 0x02; // compare match Interrupt on
#endif #endif
//setup timer1 also (for blanking pulse)
TCCR1A = 0x00;
TCCR0B = _BV(WGM12); // CTC Mode
OCR1A = 8192; // top value
TIMSK1 = _BV(OCIE1A); // compare match interrupt on
} }
@ -206,18 +232,18 @@ void tlc5940_init()
//set blank flag (disable led-outputs) //set blank flag (disable led-outputs)
//dcprog is high -> use values from dc register //dcprog is high -> use values from dc register
//vprg is high -> dot correction mode mode //vprg is high -> dot correction mode mode
COLPORT = _BV(TLC_PIN_XERR) | _BV(TLC_PIN_BLANK) | _BV(TLC_PIN_DCPRG) | _BV(TLC_PIN_VPRG); TLCPORT = _BV(TLC_PIN_XERR) | _BV(TLC_PIN_BLANK) | _BV(TLC_PIN_DCPRG) | _BV(TLC_PIN_VPRG);
//set max power (6bit * 16 LEDs) //set max power (6bit * 16 LEDs)
COLPORT |= _BV(TLC_PIN_SIN); TLCPORT |= _BV(TLC_PIN_SIN);
for(i = 0; i < 96; i++) SCLK(); for(i = 0; i < 96; i++) SCLK();
XLAT(); XLAT();
//switch to grayscale mode //switch to grayscale mode
COLPORT &= ~_BV(TLC_PIN_VPRG); TLCPORT &= ~_BV(TLC_PIN_VPRG);
//flush input shift register (12bit * 16 LEDs) //flush input shift register (12bit * 16 LEDs)
COLPORT &= ~_BV(TLC_PIN_SIN); TLCPORT &= ~_BV(TLC_PIN_SIN);
for(i = 0; i < 192; i++) SCLK(); for(i = 0; i < 192; i++) SCLK();
XLAT(); XLAT();