/* mija 2008
nanotern02A
f osc 1Mhz
timer1 PWM
ver.: 1.0
/n .. goto 1,1
/r .. goto 1,2
/f .. clear lcd
*/
//*************************************************************
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
//#include <avr/sleep.h>
#include "lcd.h"
//*************************************************************
void line_feed(void);
void PWM_init(void);
void COMP_init(void);
ISR(ANA_COMP_vect);
int main(void);
//*************************************************************
#define TEXT1 "setup"
#define MAX_BUF 16
#define FIRST 40 // *16ms time next key
#define REPEAT 10 // *16ms time repeat key
#define LIGHT PB5 // tlacitko A
#define PORT_LIGHT PORTB // nutne definovat PORT,DDR,PIN
#define DDR_LIGHT DDRB
#define TL_A PD6 // tlacitko A
#define PORT_A PORTD // nutne definovat PORT,DDR,PIN
#define DDR_A DDRD
#define PIN_A PIND
#define TL_B PB0 // tlacitko B
#define PORT_B PORTB // nutne definovat PORT,DDR,PIN
#define DDR_B DDRB
#define PIN_B PINB
#define TL_C PB2 // tlacitko C
#define PORT_C PORTB // nutne definovat PORT,DDR,PIN
#define DDR_C DDRB
#define PIN_C PINB
#define TL_D PD3 // tlacitko D
#define PORT_D PORTB // nutne definovat PORT,DDR,PIN
#define DDR_D DDRB
#define PIN_D PINB
// eeprom
#define EE_SETUP 0x03
#define EE_VOLTAGE_LO 0x00
#define EE_VOLTAGE_HI 0x01
// key
#define KEY_0 0x8
#define KEY_1 0xC
#define KEY_2 0xE
#define KEY_3 0x4
#define KEY_4 0x6
#define KEY_5 0x7
#define KEY_6 0xA
#define KEY_7 0x2
#define KEY_8 0x3
#define KEY_9 0xB
#define KEY_cr 0x1
#define KEY_esc 0x9
//interni
#define A_INPUT (!(PIN_A & _BV(TL_A)))
#define A_PULLUP (PORT_A |= _BV(TL_A))
#define A_INIT (DDR_A &= ~(_BV(TL_A)))
#define B_INPUT (!(PIN_B & _BV(TL_B)))
#define B_PULLUP (PORT_B |= _BV(TL_B))
#define B_INIT (DDR_B &= ~(_BV(TL_B)))
#define C_INPUT (!(PIN_C & _BV(TL_C)))
#define C_PULLUP (PORT_C |= _BV(TL_C))
#define C_INIT (DDR_C &= ~(_BV(TL_C)))
#define D_INPUT (!(PIN_D & _BV(TL_D)))
#define D_PULLUP (PORT_D |= _BV(TL_D))
#define D_INIT (DDR_D &= ~(_BV(TL_D)))
#define LIGHT_ON (PORT_LIGHT |= _BV(LIGHT))
#define LIGHT_OFF (PORT_LIGHT &= ~(_BV(LIGHT)))
#define LIGHT_INIT (DDR_LIGHT |= _BV(LIGHT))
//flag
volatile uint8_t flag;
#define KEY_A 0
#define KEY_B 1
#define KEY_C 2
#define KEY_D 3
#define VOLTAGE 4
#define LIGHT_SET 5
#define LIGHT_T0 6
#define LIGHT_T1 7
#define FLAG_A_SET (flag |= _BV(KEY_A))
#define FLAG_A_CLR (flag &= ~(_BV(KEY_A)))
#define FLAG_A (flag & _BV(KEY_A))
#define FLAG_B_SET (flag |= _BV(KEY_B))
#define FLAG_B_CLR (flag &= ~(_BV(KEY_B)))
#define FLAG_B (flag & _BV(KEY_B))
#define FLAG_C_SET (flag |= _BV(KEY_C))
#define FLAG_C_CLR (flag &= ~(_BV(KEY_C)))
#define FLAG_C (flag & _BV(KEY_C))
#define FLAG_D_SET (flag |= _BV(KEY_D))
#define FLAG_D_CLR (flag &= ~(_BV(KEY_D)))
#define FLAG_D (flag & _BV(KEY_D))
#define FLAG_VOLTAGE_HI (flag |= _BV(VOLTAGE))
#define FLAG_VOLTAGE_LO (flag &= ~(_BV(VOLTAGE)))
#define FLAG_VOLTAGE (flag & (_BV(VOLTAGE)))
#define FLAG_LIGHT_ON (flag |= _BV(LIGHT_SET))
#define FLAG_LIGHT_OFF (flag &= ~(_BV(LIGHT_SET)))
#define FLAG_LIGHT (flag & _BV(LIGHT_SET))
#define FLAG_T0_SET (flag |= _BV(LIGHT_T0))
#define FLAG_T0_CLR (flag &= ~(_BV(LIGHT_T0)))
#define FLAG_T0 (flag & _BV(LIGHT_T0))
#define FLAG_T1_SET (flag |= _BV(LIGHT_T1))
#define FLAG_T1_CLR (flag &= ~(_BV(LIGHT_T1)))
#define FLAG_T1 (flag & _BV(LIGHT_T1))
//*************************************************************
uint8_t a,pos;
//uint8_t buf[8] = TEXT1;
uint8_t buf_rx[MAX_BUF];
volatile uint8_t rx_shift;
volatile uint8_t tik16ms;
uint8_t lcd_shift;
enum {LED_OFF,LED_5s,LED_10s,LED_15s,LED_20s,LED_25s,LED_30s,LED_ON};
//*************************************************************
void IO_init(void)
{
LIGHT_INIT;
A_PULLUP;
B_PULLUP;
C_PULLUP;
D_PULLUP;
}
void rs232_init(void)
{
//set baud rate fixed 9600 8N1 for fosc 1Mhz
UCSRA = _BV(U2X) ;
UBRRL = 12;
UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
}
void PWM_init(void)
{
TCNT1 = 0;
OCR1B = 0x1;
DDRB |= _BV(PB4);
TCCR1A |= _BV(COM1B1) | _BV(WGM10);
TCCR1B |= _BV(WGM12) | _BV(CS10);
}
void PWM_set(void)
{
if (ACSR & _BV(ACO))
{
//OCR1BL = 0x5f;
OCR1BL = eeprom_read_byte(EE_VOLTAGE_LO);
FLAG_VOLTAGE_LO;
}
else
{
//OCR1BL = 0x17;
OCR1BL = eeprom_read_byte(EE_VOLTAGE_HI);
FLAG_VOLTAGE_HI;
}
}
void COMP_init(void)
{
ACSR = _BV(ACBG) | _BV(ACIE);
DIDR = _BV(AIN1D);
}
void timer0_init(void)
{
TCCR0B = _BV(CS01) | _BV(CS00);
TIMSK |= _BV(TOIE0);
}
ISR(TIMER0_OVF_vect) //cca 16ms tik
{
if (A_INPUT) FLAG_A_SET;else FLAG_A_CLR;
if (B_INPUT) FLAG_B_SET;else FLAG_B_CLR;
if (C_INPUT) FLAG_C_SET;else FLAG_C_CLR;
if (D_INPUT) FLAG_D_SET;else FLAG_D_CLR;
if (FLAG_LIGHT) LIGHT_ON;
else LIGHT_OFF;
if (tik16ms) tik16ms--;
}
ISR(USART_RX_vect)
{
//while ( !(UCSRA & (_BV(RXC))) );
if (++rx_shift >= MAX_BUF) rx_shift = 0;
buf_rx[rx_shift]=UDR;
}
ISR(ANA_COMP_vect)
{
//if (ACSR & _BV(ACO)) OCR1BL = 0x5f;
//else OCR1BL = 0x17;
PWM_set();
}
void put(char data)
{
while (!( UCSRA & _BV(UDRE)));
UDR = data;
}
void send(uint8_t data)
{
switch (data)
{
case (KEY_0): put('0');break;
case (KEY_1): put('1');break;
case (KEY_2): put('2');break;
case (KEY_3): put('3');break;
case (KEY_4): put('4');break;
case (KEY_5): put('5');break;
case (KEY_6): put('6');break;
case (KEY_7): put('7');break;
case (KEY_8): put('8');break;
case (KEY_9): put('9');break;
case (KEY_cr): put('\n');break;
case (KEY_esc): put('\f');break;
}
}
void delay_ms(uint8_t time)
{
while (time--) _delay_ms(1);
}
void print_lcd(char *data)
{
while (*data) LCD_putc(*data++);
}
void set(void)
{
LCD_gotoxy(1,1);
print_lcd("con. 0/1");
LCD_gotoxy(1,2);
print_lcd(" led 2-9");
while (A_INPUT);
for(;;)
{
switch (flag & 0x0f)
{
case KEY_0: OCR1BL--;break;
case KEY_1: OCR1BL++;break;
case KEY_2: LIGHT_OFF;FLAG_LIGHT_OFF;break;
case KEY_3: LIGHT_ON;FLAG_LIGHT_ON;break;
case KEY_4: break;
case KEY_esc:
{
eeprom_write_byte(EE_SETUP,flag & 0xF0);
if (FLAG_VOLTAGE) eeprom_write_byte(EE_VOLTAGE_HI,OCR1BL);
else eeprom_write_byte(EE_VOLTAGE_LO,OCR1BL);
return;
}
}
delay_ms(50);
}
}
int main(void)
{
uint8_t save_flag;
IO_init();
LCD_init();
rs232_init();
PWM_init();
COMP_init();
timer0_init();
LIGHT_OFF;
print_lcd(TEXT1);
LCD_gotoxy(1,2);
print_lcd("cr+reset");
LCD_gotoxy(1,1);
flag = 0xfE0 & eeprom_read_byte(EE_SETUP);
sei();
if (A_INPUT) set();
pos=0;
rx_shift=0;
lcd_shift=0;
save_flag=0;
for(;;)
{
if (rx_shift != lcd_shift )
{
if (++lcd_shift >= MAX_BUF) lcd_shift = 0;
a=buf_rx[lcd_shift];
switch (a)
{
case ('\n'): LCD_gotoxy(1,1);pos=0;break;
case ('\r'): pos=8;break;
case ('\f'): LCD_clear();pos=0;break;
default :if(pos == 8)
{
LCD_gotoxy(1,2);
//delay_ms(10);
}
LCD_putc(a);
if (++pos > 15)
{
pos = 0;
LCD_gotoxy(1,1);
//delay_ms(10);
}
}
}
if (flag & 0x0F)
{
if ((flag & 0x0F) != save_flag)
{
save_flag = flag & 0x0F;
send(save_flag);
tik16ms=FIRST;
}
else
{
if (!tik16ms)
{
send(save_flag);
tik16ms = REPEAT;
}
}
}
else save_flag = 0;
}
return 0;
}