From 5465febd59fcf0602d5c600da6af809995aae818 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Tue, 7 Feb 2012 20:45:45 +0100 Subject: [PATCH] working version --- main.c | 366 +++++++++++++++++++++------------------------------------ 1 file changed, 135 insertions(+), 231 deletions(-) diff --git a/main.c b/main.c index 000bf4d..d920c2d 100644 --- a/main.c +++ b/main.c @@ -39,28 +39,22 @@ * PD2 -> /RX_TX * PD3 -> /LED */ -#define TARGET_HW 1 -#define ASM_IRQS 1 -#if (TARGET_HW) #define F_CPU 8000000 -#else -#define F_CPU 7372800 -#endif #include -#define ROW1 PORTB3 -#define ROW2 PORTB2 -#define ROW3 PORTB1 -#define ROW4 PORTB0 +#define ROW1 PORTB1 /* RED */ +#define ROW2 PORTB0 /* GREEN */ +#define ROW3 PORTB3 /* BLUE */ +#define ROW4 PORTB2 /* not used */ #define RXTX PORTD2 #define LED PORTD3 //#define BAUDRATE 115200 -#if (!TARGET_HW) && (BAUDRATE) +#if (BAUDRATE) #define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1) static int uart_putchar(char c, FILE *stream) @@ -76,28 +70,21 @@ static int uart_putchar(char c, FILE *stream) } static FILE uart = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); -#endif /* (!TARGET_HW) && (BAUDRATE) */ +#endif /* (BAUDRATE) */ -static uint8_t valueR[16]; -static uint8_t valueG[16]; -static uint8_t valueB[16]; - -/* keep color in r4 */ -register uint8_t nextColor asm("r4"); - -/* keep pointer in r2:r3 */ -register uint8_t * pCurrentStep asm("r2"); +/* 16 values per color */ +static uint8_t chan_value[3][16]; /* 16 +1 * 4 values (portA, portC, OCR0, flags) per color */ -static uint8_t data[17 * 4 * 3]; +static uint8_t chan_rawdata[3][17 * 4]; -/* offsets in data array */ -#define RED_OFFSET (17 * 4 * 0) -#define GREEN_OFFSET (17 * 4 * 1) -#define BLUE_OFFSET (17 * 4 * 2) +/* used only in ISR */ +register uint8_t * pCurrentStep asm("r2"); /* r3:r2 */ +/* used to sync ISR and color_update() */ +register uint8_t nextColor asm("r4"); /* r4 */ -#if ASM_IRQS +/* worst case: 9+2+12+8+7+13 = 61 clks -> 7.625us @8MHz */ void __attribute__ ((naked)) SIG_OVERFLOW0 (void) { asm volatile( @@ -111,59 +98,49 @@ void __attribute__ ((naked)) SIG_OVERFLOW0 (void) ); asm volatile( - "clr r24 \n\t" - "out %0, r24 \n\t" /* PORTA = 0x00; */ - "out %1, r24 \n\t" /* PORTC = 0x00; */ - : - : "I" (_SFR_IO_ADDR(PORTA)), - "I" (_SFR_IO_ADDR(PORTC)) + /* disable outputs 1+1 = 2 */ + "out %0, r1 \n\t" /* PORTA = 0x00; */ + "out %1, r1 \n\t" /* PORTC = 0x00; */ + :: "I" (_SFR_IO_ADDR(PORTA)), + "I" (_SFR_IO_ADDR(PORTC)) ); asm volatile( - /* switch color, assign pCurrentStep = data + RED/GREEN/BLUE_OFFSET */ - "mov r24, %0 \n\t" - "inc %0 \n\t" /* nextColor++ */ - "cpi r24, 1 \n\t" - "brlo L_red%= \n\t" /* if (nextColor < 1) -> red */ - "breq L_green%= \n\t" /* if (nextColor == 1) -> green */ - "clr %0 \n\t" /* else set nextColor = 0, add BLUE_OFFSET */ -#if (TARGET_HW) - "ldi r24, 8 \n\t" - "out %5, r24 \n\t" -#endif /* (TARGET_HW) */ - "ldi r24, %4 \n\t" - "rjmp L_add%= \n\t" - "L_red%=: \n\t" /* red: add RED_OFFSET (do nothing) */ -#if (TARGET_HW) - "ldi r24, 2 \n\t" - "out %5, r24 \n\t" -#endif /* (TARGET_HW) */ - "rjmp L_skip%= \n\t" - "L_green%=: \n\t" /* green: add GREEN_OFFSET */ -#if (TARGET_HW) - "ldi r24, 1 \n\t" - "out %5, r24 \n\t" -#endif /* (TARGET_HW) */ - "ldi r24, %3 \n\t" - "L_add%=: \n\t" - "add r30, r24 \n\t" - "ldi r24, 0 \n\t" - "adc r31, r24 \n\t" - "L_skip%=: \n\t" - "movw %2, r30 \n\t" - : - : "r" (nextColor), - "z" (data), - "r" (pCurrentStep), - "M" (GREEN_OFFSET), - "M" (BLUE_OFFSET), - "I" (_SFR_IO_ADDR(PORTB)) - : "r24" + /* switch color and assign pCurrentStep */ + "mov r24, %0 \n\t" // 1 1 1 + "inc %0 \n\t" /* nextColor++ */ // 2 2 2 + "cpi r24, 1 \n\t" // 3 3 3 + "brlo L_red%= \n\t" /* if (nextColor < 1) -> red */ // 5 4 4 + "breq L_green%= \n\t" /* if (nextColor == 1) -> green */ // - 6 5 + "clr %0 \n\t" /* nextColor = 0; */ // - - 6 + "ldi r24, %8 \n\t" /* PORTB = (1< 4.5us @ 8MHz */ void __attribute__ ((naked)) SIG_OUTPUT_COMPARE0 (void) { asm volatile( @@ -219,7 +197,7 @@ void __attribute__ ((naked)) SIG_OUTPUT_COMPARE0 (void) ); asm volatile( - /* load table values 1+2+1+2+1+2+1+2+1 = 13 */ + /* load table values 1+1+1+1+1+1+1+1+1 = 9 */ "movw r30, %0 \n\t" "ld r24, z+ \n\t" "out %1, r24 \n\t" /* PORTA = *pCurrentStep++; */ @@ -228,23 +206,23 @@ void __attribute__ ((naked)) SIG_OUTPUT_COMPARE0 (void) "ld r24, z+ \n\t" "out %3, r24 \n\t" /* OCR0 = *pCurrentStep++; */ "ld r24, z+ \n\t" - "movw %4, r30 \n\t" + "movw %0, r30 \n\t" + :: "r" (pCurrentStep), + "I" (_SFR_IO_ADDR(PORTA)), + "I" (_SFR_IO_ADDR(PORTC)), + "I" (_SFR_IO_ADDR(OCR0)) + ); - /* check if IRQ must be disabled 1+1+1+1+1 = 5 */ - "or r24, r24 \n\t" /* if (!(*pCurrentStep++)) */ + asm volatile( + /* check if IRQ must be disabled 1+1+1+1+1 = 3/5 */ + "or r24, r24 \n\t" /* if (!(*pCurrentStep++)) { */ "brne L_skip%= \n\t" - "in r24, %5 \n\t" /* TIMSK &= ~(1<> 8) & 0xFF); /* PORTC */ } -#if (!TARGET_HW) && (BAUDRATE) +#if (BAUDRATE) void print_values(uint8_t *data) { uint8_t i; @@ -397,7 +325,9 @@ void print_values(uint8_t *data) break; } } -#endif /* (!TARGET_HW) && (BAUDRATE) */ +#else +#define print_values(data) +#endif /* (BAUDRATE) */ int main(void) { @@ -405,29 +335,21 @@ int main(void) PORTA = 0x00; DDRA = 0xFF; -#if (TARGET_HW) PORTB = 0x00; DDRB = (1<>8) & 0xFF; UBRRL = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF); @@ -437,45 +359,38 @@ int main(void) UCSRC = (1<> 8) { + case 6: + ramp = 0x0000; + /* no break */ + case 0: /* red: on, green: ramp up, blue: off */ - color[1]++; - if (color[1] == 0xFF) - ramp++; + color[0] = 0xFF; + color[1] = ramp & 0xFF; + color[2] = 0x00; break; case 1: /* red: ramp down, green: on, blue:off */ - color[0]--; - if (color[0] == 0x00) - ramp++; + color[0] = 0xFF - (ramp & 0xFF); + color[1] = 0xFF; + color[2] = 0x00; break; case 2: /* red: off, green: on, blue: ramp up */ - color[2]++; - if (color[2] == 0xFF) - ramp++; + color[0] = 0x00; + color[1] = 0xFF; + color[2] = (ramp & 0xFF); break; case 3: /* red: off, green: ramp down: blue: on */ - color[1]--; - if (color[1] == 0x00) - ramp++; + color[0] = 0x00; + color[1] = 0xFF - (ramp & 0xFF); + color[2] = 0xFF; break; case 4: /* red: ramp up, green: off, blue: on */ - color[0]++; - if (color[0] == 0xFF) - ramp++; + color[0] = (ramp & 0xFF); + color[1] = 0x00; + color[2] = 0xFF; break; case 5: /* red: on, green: off, blue: ramp down */ - color[2]--; - if (color[2] == 0x00) - ramp = 0; + color[0] = 0xFF; + color[1] = 0x00; + color[2] = 0xFF - (ramp & 0xFF); break; } - uint8_t i; + uint8_t i, j; for (i = 0; i < 16; i++) { + for (j = 0; j < 3; j++) { #if 0 - if (x == i) { - valueR[i] = color[0]; - valueG[i] = color[1]; - valueB[i] = color[2]; + if (x == i) { + chan_value[j][i] = color[j]; - } else { -// valueR[i] = 0; -// valueG[i] = 0; -// valueB[i] = 0; - - if (valueR[i] > 0) { - uint8_t tmp = (valueR[i] >> 5); - valueR[i] -= (tmp > 0) ? tmp : 1; + } else if (chan_value[j][i] > 0) { + uint8_t tmp = (chan_value[j][i] >> 5); + chan_value[j][i] -= (tmp > 0) ? tmp : 1; } - - if (valueG[i] > 0) { - uint8_t tmp = (valueG[i] >> 5); - valueG[i] -= (tmp > 0) ? tmp : 1; - } - - if (valueB[i] > 0) { - uint8_t tmp = (valueB[i] >> 5); - valueB[i] -= (tmp > 0) ? tmp : 1; - } - } #else - valueR[i] = color[0]; - valueG[i] = color[1]; - valueB[i] = color[2]; + chan_value[j][i] = color[j]; #endif + } } }