Rev 127 | Blame | Last modification | View Log | RSS feed
#include <avr/io.h>#include <avr/wdt.h>#include <avr/interrupt.h>#include <string.h>#include <util/delay.h>#include <stdlib.h>#include "avrutil.h"#include "wire.h"#include "lcd.h"#include "config.h"#include "uart.h"#include "lmd.h"#ifndef NULL#define NULL ((void *)0)#endif/* ------------------------------------------------------------------------- */#define LCD_SEND_DELAY 80#define OLED_SEND_DELAY 500#define OLED_LCDWIDTH 128#define OLED_LCDHEIGHT 64#define UART_BAUD_RATE 9600volatile uint8_t lcdTimer = LCD_SEND_DELAY;volatile uint16_t oledTimer = OLED_SEND_DELAY;volatile uint8_t tmr0_ovf = 0;char display[10];volatile struct {uint8_t current;uint8_t last;uint8_t mask;} pcInt[3];volatile struct {int8_t outer;int8_t inner;} input;volatile uint8_t doInt = 0;void pcInterrupt(uint8_t pcint);int main(void) {/*DDR : 1 = Output, 0 = InputPORT: 1 = Pullup for Input, otherwise set outputPIN : Read input pin*//*PB0 -PB1 -PB2 -PB3 -PB4 -PB5 -PB6 -PB7 -*/DDRB = 0B00000111;PORTB = 0B00000000;/*PC0 -PC1 -PC2 -PC3 -PC4 -PC5 -*/DDRC = 0B00000000;PORTC = 0B00001111;/*PD0 -PD1 -PD2 -PD3 -PD4 -PD5 - Input PcInt - * I/O Interrupt PCINT21PD6 - Output - * Status LEDPD7 - Input, Pullup - * Button*/DDRD = 0B01000000;PORTD = 0B10000000;PCMSK1 |= (( 1 << PCINT8 ) | ( 1 << PCINT9 )| ( 1 << PCINT10 )| ( 1 << PCINT11 ));PCICR |= ( 1 << PCIE1 );pcInt[1].last = PINC;pcInt[1].current = pcInt[1].last;pcInt[1].mask = 0;systime = 0;sysclockInit();uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );wdt_enable(WDTO_1S); // Watchdog for 1 secsei(); // Enable interruptsi2c_master();lcd_init();sbi(PORTD, PD6);_delay_us(100);cbi(PORTD, PD6);lcd_setCursor(0, 1);lcd_print("Time:\0");lmd_init(0x03, PB0, PB1, PB2, 2); // PORTB = 0x03, 5 digits = 0x04// Let the MAX's settle. There's also a 200us delay inside the init_delay_ms(200);uint16_t comm1[2];comm1[0] = 12010;comm1[1] = 12190;input.outer = 0;input.inner = 0;uint8_t c;for (c=0; c<=1; c++) {lmd_scanlimit(c, 0x04);lmd_decodemode(c, 0xff);lmd_dp(c, 0x04);lmd_print_u16(c, comm1[c]);}for(;;){wdt_reset();if (doInt) {pcInterrupt(doInt);doInt = 0;}#ifdef _DEBUG_if (!lcdTimer) {ultoa(systime, display, 10);lcd_overprint_right(display, 10, 6, 1);lcdTimer = LCD_SEND_DELAY;}#endifif (!oledTimer && !rbi(PIND, PD7)) {cli();statusLed(ON);//swap_u16(&comm1[0], &comm1[1]);uint16_t t = comm1[1];comm1[1] = comm1[0];comm1[0] = t;_delay_ms(100);statusLed(OFF);sei();oledTimer = OLED_SEND_DELAY;lmd_print_u16(0, comm1[0]);lmd_print_u16(1, comm1[1]);#ifdef _DEBUG_uart_puts("Swap: ");utoa(systime, display, 10);uart_puts(display);uart_puts("\r\n");#endif}if (input.inner != 0 || input.outer != 0) {int16_t delta = 0;if (input.inner) {delta = (input.inner * 5);}if (input.outer) {delta = (input.outer * 100);}input.inner = 0;input.outer = 0;comm1[1] += delta;lmd_print_u16(1, comm1[1]);}_delay_ms(1);}return 0;}void pcInterrupt(uint8_t pcint) {wdt_reset();pcInt[pcint].mask = pcInt[pcint].current ^ pcInt[pcint].last;#ifdef _DEBUG_utoa(pcInt[pcint].last, display, 2);uart_puts(display);uart_puts("\r\n");utoa(pcInt[pcint].current, display, 2);uart_puts(display);uart_puts("\r\n");utoa(pcInt[pcint].mask, display, 2);uart_puts(display);uart_puts("\r\n");#endifpcInt[pcint].last = pcInt[pcint].current;if (pcInt[pcint].mask == 0)return;// Check which pin caused the interrupt. If they both// equal 0 || 1, the pin that interrupted is the directionif (((rbi(pcInt[pcint].current, PCINT8) == 1 &&rbi(pcInt[pcint].current, PCINT9) == 1) ||(rbi(pcInt[pcint].current, PCINT8) == 0 &&rbi(pcInt[pcint].current, PCINT9) == 0))) {if (rbi(pcInt[pcint].mask, PCINT8) ) {input.outer += 1;uart_puts("+Outer\r\n");} else if (rbi(pcInt[pcint].mask, PCINT9) ) {input.outer -= 1;uart_puts("-Outer\r\n");}}if (((rbi(pcInt[pcint].current, PCINT10) == 1 &&rbi(pcInt[pcint].current, PCINT11) == 1) ||(rbi(pcInt[pcint].current, PCINT10) == 0 &&rbi(pcInt[pcint].current, PCINT11) == 0))) {if (rbi(pcInt[pcint].mask, PCINT10) ) {input.inner += 1;uart_puts("+Inner\r\n");} else if (rbi(pcInt[pcint].mask, PCINT11) ) {input.inner -= 1;uart_puts("-Inner\r\n");}}// Clear the mask so we know we've dealt with itpcInt[pcint].mask = 0;}ISR(PCINT1_vect) {pcInt[1].current = PINC;if (!doInt) {doInt = 1;}}ISR(TIMER0_OVF_vect) {tmr0_ovf++;// Clk/1 TCCR0B = (1<< CS00);//20.0Mhz, 1ms = 78ovf//16.5Mhz, 1ms = 64ovf//16.0Mhz, 1ms = 62ovf//12.0Mhz, 1ms = 46ovfif (tmr0_ovf>=64) {systime++;tmr0_ovf = 0;if (lcdTimer)lcdTimer--;if (oledTimer)oledTimer--;}}