working
This commit is contained in:
parent
c9f2f64636
commit
72226b24a9
5
Makefile
5
Makefile
@ -1,6 +1,6 @@
|
|||||||
PRG = 16ch_pwm
|
PRG = 16ch_pwm
|
||||||
OBJ = main.o
|
OBJ = main.o
|
||||||
MCU_TARGET = atmega16
|
MCU_TARGET = atmega32
|
||||||
OPTIMIZE = -O2
|
OPTIMIZE = -O2
|
||||||
|
|
||||||
DEFS =
|
DEFS =
|
||||||
@ -49,4 +49,5 @@ bin: $(PRG).bin
|
|||||||
install: text
|
install: text
|
||||||
# uisp -dprog=stk200 --erase --upload if=$(PRG).hex --verify
|
# uisp -dprog=stk200 --erase --upload if=$(PRG).hex --verify
|
||||||
# avrdude -p m16 -c butterfly -b 19200 -P /dev/ttyUSB0 -U flash:w:$(PRG).hex
|
# avrdude -p m16 -c butterfly -b 19200 -P /dev/ttyUSB0 -U flash:w:$(PRG).hex
|
||||||
avrdude -p m16 -c dragon_isp -P usb -U flash:w:$(PRG).hex
|
# avrdude -p m16 -c dragon_isp -P usb -U flash:w:$(PRG).hex
|
||||||
|
avrdude -p m32 -c dragon_isp -P usb -U flash:w:$(PRG).hex
|
||||||
|
523
main.c
523
main.c
@ -1,5 +1,5 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* C based avr910 / avr109 ISP Adapter *
|
* 16ch RGB 8bit PWM controller *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2006 - 20011 by Olaf Rempel *
|
* Copyright (C) 2006 - 20011 by Olaf Rempel *
|
||||||
* razzor AT kopf MINUS tisch DOT de *
|
* razzor AT kopf MINUS tisch DOT de *
|
||||||
@ -24,22 +24,51 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* using ATmega16 @7.3728MHz:
|
* using ATmega32 @8MHz:
|
||||||
* Fuse H: 0xDA (512 words bootloader, jtag disabled)
|
* Fuse H: 0xD9 (no bootloader, jtag disabled)
|
||||||
* Fuse L: 0xFF (ext. Crystal)
|
* Fuse L: 0xD4 (int. 8MHz Osz, fast rising power, no BOD)
|
||||||
|
*
|
||||||
|
* PA0..7 -> COL1..8
|
||||||
|
* PC0..7 -> COL9..16
|
||||||
|
* PB0 / PD7(OC2) -> ROW4
|
||||||
|
* PB1 / PD5(OC1A) -> ROW3
|
||||||
|
* PB2 / PD4(OC1B) -> ROW2
|
||||||
|
* PB3(OC0) / PD6 -> ROW1
|
||||||
|
* PD0 -> RXD
|
||||||
|
* PD1 -> TXD
|
||||||
|
* 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
|
#define F_CPU 7372800
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
|
||||||
#define BAUDRATE 9600
|
#define ROW1 PORTB3
|
||||||
|
#define ROW2 PORTB2
|
||||||
|
#define ROW3 PORTB1
|
||||||
|
#define ROW4 PORTB0
|
||||||
|
|
||||||
|
#define RXTX PORTD2
|
||||||
|
#define LED PORTD3
|
||||||
|
|
||||||
|
//#define BAUDRATE 115200
|
||||||
|
|
||||||
|
#if (!TARGET_HW) && (BAUDRATE)
|
||||||
#define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1)
|
#define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1)
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int uart_putchar(char c, FILE *stream)
|
static int uart_putchar(char c, FILE *stream)
|
||||||
{
|
{
|
||||||
if (c == '\n')
|
if (c == '\n') {
|
||||||
uart_putchar('\r', stream);
|
loop_until_bit_is_set(UCSRA, UDRE);
|
||||||
|
UDR = '\r';
|
||||||
|
}
|
||||||
|
|
||||||
loop_until_bit_is_set(UCSRA, UDRE);
|
loop_until_bit_is_set(UCSRA, UDRE);
|
||||||
UDR = c;
|
UDR = c;
|
||||||
@ -47,97 +76,243 @@ static int uart_putchar(char c, FILE *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static FILE uart = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
static FILE uart = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
||||||
#endif
|
#endif /* (!TARGET_HW) && (BAUDRATE) */
|
||||||
|
|
||||||
static uint8_t valueR[16] = {
|
static uint8_t valueR[16];
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
static uint8_t valueG[16];
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
static uint8_t valueB[16];
|
||||||
// 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
|
|
||||||
// 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t valueG[16] = {
|
/* keep color in r4 */
|
||||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
register uint8_t nextColor asm("r4");
|
||||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
|
||||||
// 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0,
|
|
||||||
// 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8,
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t valueB[16] = {
|
/* keep pointer in r2:r3 */
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
register uint8_t * pCurrentStep asm("r2");
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
// 0xF1, 0xF3, 0xF5, 0xF7, 0xF9, 0xFB, 0xFD, 0xFF,
|
|
||||||
// 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t *current_comp_reg;
|
/* 16 +1 * 4 values (portA, portC, OCR0, flags) per color */
|
||||||
static uint8_t comp_regR[16];
|
static uint8_t data[17 * 4 * 3];
|
||||||
static uint8_t comp_regG[16];
|
|
||||||
static uint8_t comp_regB[16];
|
|
||||||
|
|
||||||
static uint16_t *current_port_reg;
|
/* offsets in data array */
|
||||||
static uint16_t port_regR[16 +1];
|
#define RED_OFFSET (17 * 4 * 0)
|
||||||
static uint16_t port_regG[16 +1];
|
#define GREEN_OFFSET (17 * 4 * 1)
|
||||||
static uint16_t port_regB[16 +1];
|
#define BLUE_OFFSET (17 * 4 * 2)
|
||||||
|
|
||||||
static uint8_t current_color;
|
|
||||||
|
#if ASM_IRQS
|
||||||
|
void __attribute__ ((naked)) SIG_OVERFLOW0 (void)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
/* save registers 2+1+2+2+2 = 9 */
|
||||||
|
"push r24 \n\t"
|
||||||
|
"in r24, __SREG__ \n\t"
|
||||||
|
"push r24 \n\t"
|
||||||
|
"push r30 \n\t"
|
||||||
|
"push r31 \n\t"
|
||||||
|
::
|
||||||
|
);
|
||||||
|
|
||||||
|
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))
|
||||||
|
);
|
||||||
|
|
||||||
|
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"
|
||||||
|
);
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
/* load table values */
|
||||||
|
"movw r30, %0 \n\t"
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"out %1, r24 \n\t" /* PORTA = *pCurrentStep++; */
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"out %2, r24 \n\t" /* PORTC = *pCurrentStep++; */
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"out %3, r24 \n\t" /* OCR0 = *pCurrentStep++; */
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"movw %4, r30 \n\t"
|
||||||
|
|
||||||
|
/* check if IRQ must be enabled */
|
||||||
|
"or r24, r24 \n\t" /* if (*pCurrentStep++) { */
|
||||||
|
"breq L_skip%= \n\t"
|
||||||
|
"ldi r24, %5 \n\t" /* TIFR = (1<<OCF0); */
|
||||||
|
"out %6, r24 \n\t"
|
||||||
|
"in r24, %7 \n\t" /* TIMSK |= (1<<OCIE0); */
|
||||||
|
"ori r24, %8 \n\t"
|
||||||
|
"out %7, r24 \n\t"
|
||||||
|
"L_skip%=: \n\t" /* } */
|
||||||
|
: "=r" (pCurrentStep)
|
||||||
|
: "I" (_SFR_IO_ADDR(PORTA)),
|
||||||
|
"I" (_SFR_IO_ADDR(PORTC)),
|
||||||
|
"I" (_SFR_IO_ADDR(OCR0)),
|
||||||
|
"0" (pCurrentStep),
|
||||||
|
"M" ((1<<OCF0)),
|
||||||
|
"I" (_SFR_IO_ADDR(TIFR)),
|
||||||
|
"I" (_SFR_IO_ADDR(TIMSK)),
|
||||||
|
"M" ((1<<OCIE0))
|
||||||
|
: "r24", "r30", "r31"
|
||||||
|
);
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
/* restore registers 2+2+2+1+2+4 = 13 */
|
||||||
|
"pop r31 \n\t"
|
||||||
|
"pop r30 \n\t"
|
||||||
|
"pop r24 \n\t"
|
||||||
|
"out __SREG__, r24 \n\t"
|
||||||
|
"pop r24 \n\t"
|
||||||
|
"reti \n\t"
|
||||||
|
::
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__ ((naked)) SIG_OUTPUT_COMPARE0 (void)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
/* save registers 2+1+2+2+2 = 9 */
|
||||||
|
"push r24 \n\t"
|
||||||
|
"in r24, __SREG__ \n\t"
|
||||||
|
"push r24 \n\t"
|
||||||
|
"push r30 \n\t"
|
||||||
|
"push r31 \n\t"
|
||||||
|
::
|
||||||
|
);
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
/* load table values 1+2+1+2+1+2+1+2+1 = 13 */
|
||||||
|
"movw r30, %0 \n\t"
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"out %1, r24 \n\t" /* PORTA = *pCurrentStep++; */
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"out %2, r24 \n\t" /* PORTC = *pCurrentStep++; */
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"out %3, r24 \n\t" /* OCR0 = *pCurrentStep++; */
|
||||||
|
"ld r24, z+ \n\t"
|
||||||
|
"movw %4, r30 \n\t"
|
||||||
|
|
||||||
|
/* check if IRQ must be disabled 1+1+1+1+1 = 5 */
|
||||||
|
"or r24, r24 \n\t" /* if (!(*pCurrentStep++)) */
|
||||||
|
"brne L_skip%= \n\t"
|
||||||
|
"in r24, %5 \n\t" /* TIMSK &= ~(1<<OCIE0); */
|
||||||
|
"andi r24, %6 \n\t"
|
||||||
|
"out %5, r24 \n\t"
|
||||||
|
"L_skip%=: \n\t"
|
||||||
|
: "=r" (pCurrentStep)
|
||||||
|
: "I" (_SFR_IO_ADDR(PORTA)),
|
||||||
|
"I" (_SFR_IO_ADDR(PORTC)),
|
||||||
|
"I" (_SFR_IO_ADDR(OCR0)),
|
||||||
|
"0" (pCurrentStep),
|
||||||
|
"I" (_SFR_IO_ADDR(TIMSK)),
|
||||||
|
"M" (0xFD) /* ~(1<<OCIE0) */
|
||||||
|
: "r24", "r30", "r31"
|
||||||
|
);
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
/* restore registers 2+2+2+1+2+4 = 13 */
|
||||||
|
"pop r31 \n\t"
|
||||||
|
"pop r30 \n\t"
|
||||||
|
"pop r24 \n\t"
|
||||||
|
"out __SREG__, r24 \n\t"
|
||||||
|
"pop r24 \n\t"
|
||||||
|
"reti \n\t"
|
||||||
|
::
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !ASM_IRQS */
|
||||||
|
|
||||||
ISR(SIG_OVERFLOW0)
|
ISR(SIG_OVERFLOW0)
|
||||||
{
|
{
|
||||||
#if 0
|
switch (nextColor++) {
|
||||||
/* switch color */
|
case 0:
|
||||||
switch (current_color) {
|
pCurrentStep = data + RED_OFFSET;
|
||||||
case 0: /* RED */
|
#if (TARGET_HW)
|
||||||
current_comp_reg = comp_regR;
|
PORTB = 0x02;
|
||||||
current_port_reg = port_regR;
|
#endif /* (TARGET_HW) */
|
||||||
current_color = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* GREEN */
|
case 1:
|
||||||
current_comp_reg = comp_regG;
|
pCurrentStep = data + GREEN_OFFSET;
|
||||||
current_port_reg = port_regG;
|
#if (TARGET_HW)
|
||||||
current_color = 2;
|
PORTB = 0x01;
|
||||||
|
#endif /* (TARGET_HW) */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* BLUE */
|
default:
|
||||||
current_comp_reg = comp_regB;
|
pCurrentStep = data + BLUE_OFFSET;
|
||||||
current_port_reg = port_regB;
|
nextColor = 0;
|
||||||
current_color = 0;
|
#if (TARGET_HW)
|
||||||
|
PORTB = 0x08;
|
||||||
|
#endif /* (TARGET_HW) */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
current_comp_reg = comp_regR;
|
|
||||||
current_port_reg = port_regR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint16_t port_reg = *current_port_reg++;
|
PORTA = *pCurrentStep++;
|
||||||
PORTA = (port_reg & 0xFF);
|
PORTC = *pCurrentStep++;
|
||||||
PORTC = (port_reg >> 8) & 0xFF;
|
OCR0 = *pCurrentStep++;
|
||||||
|
|
||||||
/* enable compare interrupts if any pin is active */
|
if (*pCurrentStep++) {
|
||||||
if (port_reg != 0x0000) {
|
TIFR = (1<<OCF0);
|
||||||
TIMSK |= (1<<OCIE0);
|
TIMSK |= (1<<OCIE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
OCR0 = *current_comp_reg++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(SIG_OUTPUT_COMPARE0)
|
ISR(SIG_OUTPUT_COMPARE0)
|
||||||
{
|
{
|
||||||
uint16_t port_reg = *current_port_reg++;
|
PORTA = *pCurrentStep++;
|
||||||
PORTA = (port_reg & 0xFF);
|
PORTC = *pCurrentStep++;
|
||||||
PORTC = (port_reg >> 8) & 0xFF;
|
OCR0 = *pCurrentStep++;
|
||||||
|
|
||||||
/* no further compare interrupts needed */
|
if (!(*pCurrentStep++)) {
|
||||||
if (port_reg == 0x0000) {
|
|
||||||
TIMSK &= ~(1<<OCIE0);
|
TIMSK &= ~(1<<OCIE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
OCR0 = *current_comp_reg++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calculate_timer_values(uint8_t *value, uint8_t *comp_reg, uint16_t *port_reg)
|
#endif /* ASM_IRQS */
|
||||||
|
|
||||||
|
static void calculate_timer_values(uint8_t *value, uint8_t *pDataStart)
|
||||||
{
|
{
|
||||||
|
uint8_t *pData = pDataStart +4; /* skip first entry (init) */
|
||||||
uint8_t index = 0;
|
uint8_t index = 0;
|
||||||
uint16_t chan_used = 0xFFFF;
|
uint16_t chan_used = 0xFFFF;
|
||||||
uint16_t chan_init = 0xFFFF;
|
uint16_t chan_init = 0xFFFF;
|
||||||
@ -176,38 +351,83 @@ static void calculate_timer_values(uint8_t *value, uint8_t *comp_reg, uint16_t *
|
|||||||
|
|
||||||
chan_used &= chan_tmp;
|
chan_used &= chan_tmp;
|
||||||
|
|
||||||
// TODO: what if all channels are 0xFF, old value?
|
|
||||||
if (min_value < 0xFF) {
|
if (min_value < 0xFF) {
|
||||||
comp_reg[index] = min_value -1;
|
/* set new outputs */
|
||||||
port_reg[index +1] = chan_used;
|
*pData++ = (chan_used & 0xFF); /* PORTA */
|
||||||
|
*pData++ = ((chan_used >> 8) & 0xFF); /* PORTC */
|
||||||
|
|
||||||
|
/* previous step needs timervalue and enable IRQ */
|
||||||
|
*(pData++ -4) = min_value -0; /* OCR0 */ /* FIXME: -1 ? */
|
||||||
|
*(pData++ -4) = 0x01; /* flags */
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fill all remaining slots */
|
||||||
while (index < 16) {
|
while (index < 16) {
|
||||||
comp_reg[index] = 0x00;
|
/* repeat enabled outputs */
|
||||||
port_reg[index +1] = chan_used;
|
*pData++ = (chan_used & 0xFF); /* PORTA */
|
||||||
|
*pData++ = ((chan_used >> 8) & 0xFF); /* PORTC */
|
||||||
|
|
||||||
|
/* previous step was last one (no timevalue / disable IRQ) */
|
||||||
|
*(pData++ -4) = 0x00; /* OCR0 */
|
||||||
|
*(pData++ -4) = 0x00; /* flags */
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
port_reg[0] = chan_init;
|
/* first slot/init: enable only channels that are > 0 */
|
||||||
|
pData = pDataStart;
|
||||||
|
*pData++ = (chan_init & 0xFF); /* PORTA */
|
||||||
|
*pData++ = ((chan_init >> 8) & 0xFF); /* PORTC */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (!TARGET_HW) && (BAUDRATE)
|
||||||
|
void print_values(uint8_t *data)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
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 (data[(i<<2) +3] == 0x00)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* (!TARGET_HW) && (BAUDRATE) */
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/* 16 PWM Outputs */
|
/* 16 PWM Outputs */
|
||||||
PORTA = 0x00;
|
PORTA = 0x00;
|
||||||
PORTC = 0x00;
|
|
||||||
DDRA = 0xFF;
|
DDRA = 0xFF;
|
||||||
|
|
||||||
|
#if (TARGET_HW)
|
||||||
|
PORTB = 0x00;
|
||||||
|
DDRB = (1<<ROW1) | (1<<ROW2) | (1<<ROW3) | (1<<ROW4);
|
||||||
|
#endif /* (TARGET_HW) */
|
||||||
|
|
||||||
|
PORTC = 0x00;
|
||||||
DDRC = 0xFF;
|
DDRC = 0xFF;
|
||||||
|
|
||||||
/* timer0, FCPU/256, overflow interrupt */
|
#if (TARGET_HW)
|
||||||
TCCR0 = (1<<CS02);
|
PORTD = (1<<RXTX) | (1<<LED);
|
||||||
|
DDRD = (1<<RXTX) | (1<<LED);
|
||||||
|
#endif /* (TARGET_HW) */
|
||||||
|
|
||||||
|
/* timer0, FCPU/64, overflow interrupt */
|
||||||
|
#if (ASM_IRQS)
|
||||||
|
TCCR0 = (1<<CS01) | (1<<CS00); /* FCPU/64 */
|
||||||
|
#else /* (!ASM_IRQS) */
|
||||||
|
TCCR0 = (1<<CS02); /* FCPU/256 */
|
||||||
|
#endif /* (ASM_IRQS) */
|
||||||
TIMSK = (1<<TOIE0);
|
TIMSK = (1<<TOIE0);
|
||||||
TCNT0 = 0x00;
|
TCNT0 = 0x00;
|
||||||
|
|
||||||
|
#if (!TARGET_HW) && (BAUDRATE)
|
||||||
/* Set baud rate */
|
/* Set baud rate */
|
||||||
UBRRH = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
|
UBRRH = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
|
||||||
UBRRL = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
|
UBRRL = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
|
||||||
@ -216,21 +436,140 @@ int main(void)
|
|||||||
UCSRB = (1<<TXEN) | (1<<RXEN);
|
UCSRB = (1<<TXEN) | (1<<RXEN);
|
||||||
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
|
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
|
||||||
|
|
||||||
// fprintf(&uart, "good morning dave\n");
|
fprintf(&uart, "good morning dave\n");
|
||||||
|
#endif /* (!TARGET_HW) && (BAUDRATE) */
|
||||||
PORTA = 0x01;
|
|
||||||
calculate_timer_values(valueR, comp_regR, port_regR);
|
|
||||||
|
|
||||||
PORTA = 0x02;
|
|
||||||
calculate_timer_values(valueG, comp_regG, port_regG);
|
|
||||||
|
|
||||||
PORTA = 0x04;
|
|
||||||
calculate_timer_values(valueB, comp_regB, port_regB);
|
|
||||||
|
|
||||||
PORTA = 0x00;
|
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
while (1);
|
|
||||||
|
uint8_t x = 0;
|
||||||
|
uint8_t xdir = 1;
|
||||||
|
uint8_t ramp = 0;
|
||||||
|
uint8_t color[3] = { 0xFF, 0x00, 0x00 };
|
||||||
|
uint8_t step = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint8_t color_update = 0x07;
|
||||||
|
while (color_update) {
|
||||||
|
if ((color_update & 0x01) && (nextColor == 2)) {
|
||||||
|
calculate_timer_values(valueR, data + RED_OFFSET);
|
||||||
|
color_update &= ~(0x01);
|
||||||
|
#if (!TARGET_HW) && (BAUDRATE)
|
||||||
|
print_values(data + RED_OFFSET);
|
||||||
|
#endif /* (!TARGET_HW) && (BAUDRATE) */
|
||||||
|
|
||||||
|
} else if ((color_update & 0x02) && (nextColor == 0)) {
|
||||||
|
calculate_timer_values(valueG, data + GREEN_OFFSET);
|
||||||
|
color_update &= ~(0x02);
|
||||||
|
#if (!TARGET_HW) && (BAUDRATE)
|
||||||
|
print_values(data + GREEN_OFFSET);
|
||||||
|
#endif /* (!TARGET_HW) && (BAUDRATE) */
|
||||||
|
|
||||||
|
} else if ((color_update & 0x04) && (nextColor == 1)) {
|
||||||
|
calculate_timer_values(valueB, data + BLUE_OFFSET);
|
||||||
|
color_update &= ~(0x04);
|
||||||
|
#if (!TARGET_HW) && (BAUDRATE)
|
||||||
|
print_values(data + BLUE_OFFSET);
|
||||||
|
#endif /* (!TARGET_HW) && (BAUDRATE) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (TARGET_HW)
|
||||||
|
PORTD ^= (1<<LED);
|
||||||
|
#endif /* (TARGET_HW) */
|
||||||
|
|
||||||
|
step++;
|
||||||
|
if (step == 16) {
|
||||||
|
step = 0;
|
||||||
|
|
||||||
|
if (xdir) {
|
||||||
|
x++;
|
||||||
|
if (x == 0x05)
|
||||||
|
x = 0x08;
|
||||||
|
else if (x == 0x0C)
|
||||||
|
xdir = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
x--;
|
||||||
|
if (x == 0x00)
|
||||||
|
xdir = 1;
|
||||||
|
else if (x == 0x07)
|
||||||
|
x = 0x04;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ramp) {
|
||||||
|
case 0: /* red: on, green: ramp up, blue: off */
|
||||||
|
color[1]++;
|
||||||
|
if (color[1] == 0xFF)
|
||||||
|
ramp++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* red: ramp down, green: on, blue:off */
|
||||||
|
color[0]--;
|
||||||
|
if (color[0] == 0x00)
|
||||||
|
ramp++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* red: off, green: on, blue: ramp up */
|
||||||
|
color[2]++;
|
||||||
|
if (color[2] == 0xFF)
|
||||||
|
ramp++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: /* red: off, green: ramp down: blue: on */
|
||||||
|
color[1]--;
|
||||||
|
if (color[1] == 0x00)
|
||||||
|
ramp++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: /* red: ramp up, green: off, blue: on */
|
||||||
|
color[0]++;
|
||||||
|
if (color[0] == 0xFF)
|
||||||
|
ramp++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: /* red: on, green: off, blue: ramp down */
|
||||||
|
color[2]--;
|
||||||
|
if (color[2] == 0x00)
|
||||||
|
ramp = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
#if 0
|
||||||
|
if (x == i) {
|
||||||
|
valueR[i] = color[0];
|
||||||
|
valueG[i] = color[1];
|
||||||
|
valueB[i] = color[2];
|
||||||
|
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user