diff --git a/Makefile b/Makefile index 8fe4940..4f69a7f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -PRG = 16ch_pwm +PRG = rgb16mpm OBJ = main.o MCU_TARGET = atmega32 -OPTIMIZE = -O2 +OPTIMIZE = -Os DEFS = LIBS = diff --git a/eagle/rgb16mpm-bot.png b/eagle/rgb16mpm-bot.png new file mode 100644 index 0000000..56f3a6c Binary files /dev/null and b/eagle/rgb16mpm-bot.png differ diff --git a/eagle/rgb16mpm-sch.png b/eagle/rgb16mpm-sch.png new file mode 100644 index 0000000..aa94497 Binary files /dev/null and b/eagle/rgb16mpm-sch.png differ diff --git a/eagle/rgb16mpm-top.png b/eagle/rgb16mpm-top.png new file mode 100644 index 0000000..ba5449d Binary files /dev/null and b/eagle/rgb16mpm-top.png differ diff --git a/eagle/rgb16mpm.brd b/eagle/rgb16mpm.brd new file mode 100644 index 0000000..2b740cd Binary files /dev/null and b/eagle/rgb16mpm.brd differ diff --git a/eagle/rgb16mpm.sch b/eagle/rgb16mpm.sch new file mode 100644 index 0000000..a40905a Binary files /dev/null and b/eagle/rgb16mpm.sch differ diff --git a/main.c b/main.c index d920c2d..7e53a99 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ /*************************************************************************** * 16ch RGB 8bit PWM controller * * * - * Copyright (C) 2006 - 20011 by Olaf Rempel * + * Copyright (C) 2011 - 2012 by Olaf Rempel * * razzor AT kopf MINUS tisch DOT de * * * * This program is free software; you can redistribute it and/or modify * @@ -20,6 +20,7 @@ ***************************************************************************/ #include #include +#include #include @@ -30,10 +31,10 @@ * * PA0..7 -> COL1..8 * PC0..7 -> COL9..16 - * PB0 / PD7(OC2) -> ROW4 - * PB1 / PD5(OC1A) -> ROW3 - * PB2 / PD4(OC1B) -> ROW2 - * PB3(OC0) / PD6 -> ROW1 + * PB0 / PD7(OC2) -> ROW4 (OC2 not used) + * PB1 / PD5(OC1A) -> ROW3 (OC1A not used) + * PB2 / PD4(OC1B) -> ROW2 (OC1B not used) + * PB3(OC0) / PD6 -> ROW1 (OC0 not used) * PD0 -> RXD * PD1 -> TXD * PD2 -> /RX_TX @@ -41,7 +42,6 @@ */ #define F_CPU 8000000 - #include #define ROW1 PORTB1 /* RED */ @@ -49,43 +49,47 @@ #define ROW3 PORTB3 /* BLUE */ #define ROW4 PORTB2 /* not used */ -#define RXTX PORTD2 +#define RXTX PORTD2 /* RS485 TX enable */ #define LED PORTD3 -//#define BAUDRATE 115200 +/* running without mpmboot? */ +#define STANDALONE 0 + +#if (STANDALONE) +#define OSCCAL 0xAA +#define BAUDRATE 115200 +#define MPM_ADDRESS 0x11 -#if (BAUDRATE) #define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1) +#endif /* STANDALONE */ -static int uart_putchar(char c, FILE *stream) -{ - if (c == '\n') { - loop_until_bit_is_set(UCSRA, UDRE); - UDR = '\r'; - } +const static uint8_t versioninfo[16] = "rgb16mpm v0.99"; - loop_until_bit_is_set(UCSRA, UDRE); - UDR = c; - return 0; -} - -static FILE uart = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); -#endif /* (BAUDRATE) */ +#define CMD_WAIT 0x00 +#define CMD_SWITCH_MODE 0x01 +#define CMD_GET_VERSION 0x02 +// #define CMD_GET_CHIPINFO 0x03 +// #define CMD_READ_MEMORY 0x11 +// #define CMD_WRITE_MEMORY 0x12 +#define CMD_WRITE_COLOR 0x81 +#define CMD_WRITE_RAW_COLOR 0x82 +#define CMD_READ_RAW_COLOR 0x83 +#define CMD_WRITE_CONFIG 0x81 /* 16 values per color */ static uint8_t chan_value[3][16]; -/* 16 +1 * 4 values (portA, portC, OCR0, flags) per color */ +/* (16 +1) * 4 values (portA, portC, OCR0, flags) per color */ static uint8_t chan_rawdata[3][17 * 4]; -/* used only in ISR */ +/* used only in softpwm ISRs */ register uint8_t * pCurrentStep asm("r2"); /* r3:r2 */ -/* used to sync ISR and color_update() */ +/* used to sync softpwm ISRs and color_update() */ register uint8_t nextColor asm("r4"); /* r4 */ /* worst case: 9+2+12+8+7+13 = 61 clks -> 7.625us @8MHz */ -void __attribute__ ((naked)) SIG_OVERFLOW0 (void) +ISR(TIMER0_OVF_vect, ISR_NAKED) { asm volatile( /* save registers 2+1+2+2+2 = 9 */ @@ -106,30 +110,29 @@ void __attribute__ ((naked)) SIG_OVERFLOW0 (void) ); asm volatile( - /* switch color and assign pCurrentStep */ + /* switch color and assign pCurrentStep */ // R G B "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) +ISR(TIMER0_COMP_vect, ISR_NAKED) { asm volatile( /* save registers 2+1+2+2+2 = 9 */ @@ -237,7 +240,7 @@ void __attribute__ ((naked)) SIG_OUTPUT_COMPARE0 (void) ); } - +/* calc chan_valueX => chan_rawdataX */ static void calculate_timer_values(uint8_t *value, uint8_t *pDataStart) { uint8_t *pData = pDataStart +4; /* skip first entry (init) */ @@ -285,7 +288,7 @@ static void calculate_timer_values(uint8_t *value, uint8_t *pDataStart) *pData++ = ((chan_used >> 8) & 0xFF); /* PORTC */ /* previous step needs timervalue and enable IRQ */ - *(pData++ -4) = min_value -0; /* OCR0 */ /* FIXME: -1 ? */ + *(pData++ -4) = min_value; /* OCR0 */ *(pData++ -4) = 0x01; /* flags */ } @@ -311,55 +314,149 @@ static void calculate_timer_values(uint8_t *value, uint8_t *pDataStart) *pData++ = ((chan_init >> 8) & 0xFF); /* PORTC */ } -#if (BAUDRATE) -void print_values(uint8_t *data) +static uint8_t rx_cmd; +static uint16_t rx_bcnt = 0xFF; +static uint16_t rx_length; + +static uint8_t tx_cmd; +static uint8_t tx_cause; +static uint16_t tx_length; +static uint16_t tx_bcnt; + +ISR(USART_RXC_vect) { - uint8_t i; + uint8_t data = UDR; + sei(); - for (i = 0; i < 17; i++) { - fprintf(&uart, "%2d: %02X %02X %02X %02X\n", i, - data[(i<<2)], data[(i<<2) +1], - data[(i<<2) +2], data[(i<<2) +3]); + if (rx_bcnt == 0xFF) { + /* MPM address stored in TWI address register by bootloader */ + if (data == TWAR) { + UCSRA &= ~(1<> 8); + + } else if (tx_bcnt == 3) { + data = (tx_length & 0xFF); + + } else if (tx_cmd == CMD_GET_VERSION) { + data = versioninfo[pos]; + + } else { + data = 0xAA; + } + + UDR = data; + + /* re-enable for next round */ + UCSRB |= (1<>8) & 0xFF; UBRRL = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF); - /* enable usart with 8n1 */ - UCSRB = (1<