From 0a60a76afcf938c6885395fb16b6c168179921e5 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 1 Apr 2012 00:22:16 +0200 Subject: adapted to ATtiny26 / sublab setup --- .gitignore | 3 + Makefile | 19 +++++ clock.c | 27 ------- clock.h | 4 + lcd.c | 69 ++++++++++++++++ lcd.h | 16 ++++ main.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ main.h | 15 +--- max7219.c | 133 ------------------------------- max7219.h | 51 ------------ timebase.c | 16 ++-- types.h | 7 +- 12 files changed, 371 insertions(+), 255 deletions(-) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 lcd.c create mode 100644 lcd.h delete mode 100644 max7219.c delete mode 100644 max7219.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ea87e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.elf +*.*hex diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..38b4e72 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +.PHONY: love flash +love: sublab77.ihex + +CFLAGS=-Wall -Wextra -pedantic -std=c99 -Os -DF_CPU=1000000 -mmcu=attiny26 + +%.o: %.c + avr-gcc $(CFLAGS) -c -o $@ $< +ifdef WHOPR +sublab77.elf: main.c + avr-gcc $(CFLAGS) -DWHOPR -o $@ $^ + avr-size $@ +else +sublab77.elf: clock.o dcf77.o lcd.o main.o timebase.o + avr-gcc -Os -mmcu=attiny26 -o $@ $^ + avr-size $@ +endif + +sublab77.ihex: sublab77.elf + objcopy -Oihex $^ $@ diff --git a/clock.c b/clock.c index e6fba14..f40c6aa 100644 --- a/clock.c +++ b/clock.c @@ -9,39 +9,12 @@ #include "main.h" #include "clock.h" -#include "max7219.h" #include "timebase.h" #include "dcf77.h" struct time data time; -void display_date( void ) -{ - displaymem[7] = time.day / 10; - displaymem[6] = time.day % 10 | ATTRIB_DP; - displaymem[5] = time.month / 10; - displaymem[4] = time.month % 10 | ATTRIB_DP; - displaymem[3] = 2; - displaymem[2] = 0; - displaymem[1] = time.year / 10; - displaymem[0] = time.year % 10; -} - - -void display_time(void) -{ - displaymem[7] = time.hour / 10; - displaymem[6] = time.hour % 10; - - displaymem[4] = time.minute / 10; - displaymem[3] = time.minute % 10; - - displaymem[1] = time.second / 10; - displaymem[0] = time.second % 10; -} - - u8 code MDAYS[] = { 29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; diff --git a/clock.h b/clock.h index 35eaa5a..51a7a59 100644 --- a/clock.h +++ b/clock.h @@ -1,3 +1,5 @@ +#ifndef _CLOCK_H +#define _CLOCK_H struct time { u8 second; @@ -14,3 +16,5 @@ extern struct time time; void display_date(void); void display_time(void); void clock( void ); + +#endif /* _CLOCK_H */ diff --git a/lcd.c b/lcd.c new file mode 100644 index 0000000..927b90f --- /dev/null +++ b/lcd.c @@ -0,0 +1,69 @@ +#include "lcd.h" + +#include +#include + +#define B_SRCLK PB0 +#define B_LCDE PB3 +#define B_SRD_LCDRS PB4 + +static void lcd_pin(bool value) +{ + /* cheat, put the clock in front. + * result: + * clk, d0 | clk, d1 | clk... d7 | clk, rs. + * ^- first clk ignored ^- last clk from setting R/S + */ + PORTB |= (1 << B_SRCLK); + PORTB &= ~(1 << B_SRCLK); + + if (value) + PORTB |= (1 << B_SRD_LCDRS); + else + PORTB &= ~(1 << B_SRD_LCDRS); +} + +void lcd_command(uint8_t cmd, bool isdata) +{ + uint8_t i; + + for (i = 1; i; i <<= 2) + lcd_pin(cmd & i); + for (i = 1 << 7; i; i >>= 2) + lcd_pin(cmd & i); + + lcd_pin(isdata); + __asm__ ("nop\n"); + PORTB |= (1 << B_LCDE); + __asm__ ("nop\n"); + PORTB &= ~(1 << B_LCDE); + __asm__ ("nop\n"); + if (!isdata) + _delay_us(50); +} + +void lcd_puts(const char * PROGMEM ptr, uint8_t cnt) +{ + while (cnt--) { + uint8_t ch = __LPM(ptr++); + lcd_put(ch); + } +} + +const char PROGMEM boot[] = "boot"; + +void lcd_init(void) +{ + PORTB &= ~((1 << B_SRCLK) | (1 << B_LCDE) | (1 << B_SRD_LCDRS)); + DDRB |= (1 << B_SRCLK) | (1 << B_LCDE) | (1 << B_SRD_LCDRS); + _delay_ms(15); + + lcd_command(0x38, 0); + lcd_command(0x0c, 0); + lcd_command(0x06, 0); + lcd_command(0x02, 0); + _delay_ms(2); + + lcd_line1(); + lcd_puts(boot, sizeof(boot) - 1); +} diff --git a/lcd.h b/lcd.h new file mode 100644 index 0000000..333856d --- /dev/null +++ b/lcd.h @@ -0,0 +1,16 @@ +#ifndef _LCD_H +#define _LCD_H + +#include +#include +#include + +extern void lcd_init(void); +extern void lcd_command(uint8_t cmd, bool isdata); +extern void lcd_puts(const char * PROGMEM ptr, uint8_t cnt); + +#define lcd_put(ch) lcd_command(ch, 1) +#define lcd_line1() lcd_command(0x80, 0) +#define lcd_line2() lcd_command(0xc0, 0) + +#endif /* _LCD_H */ diff --git a/main.c b/main.c index f130906..cd9666a 100644 --- a/main.c +++ b/main.c @@ -1,46 +1,260 @@ #include "main.h" -#include "max7219.h" #include "clock.h" #include "timebase.h" #include "dcf77.h" +#include "lcd.h" +#include +#include +#include + +#ifdef WHOPR +#include "clock.c" +#include "timebase.c" +#include "dcf77.c" +#include "lcd.c" +#endif + +#define B_SW_BACK PINB5 +#define B_SW_FRWD PINB6 + +#define A_OCPL_A PA5 +#define A_OCPL_B PA6 + +#define EE_HOUR 0 +#define EE_MINUTE 1 +#define EE_CKSUM 2 +#define EE_BOOTC 4 + +static uint8_t ext_hour, ext_minute; +static uint16_t bootcount; + +#define WAIT 64 +uint8_t waitctr = 0; +enum stepstate { + STEP_INACTIVE = 0, + STEP_ACTIVE, +} stepstate = STEP_INACTIVE; + +const char PROGMEM disp[2] = {'_', '+'}; +const char PROGMEM status[24] = "normalsync adj + adj - "; +const char PROGMEM cksumfail[] = "cksum fail"; + +static void puttwo(uint8_t arg) +{ + uint8_t b = '0', a = '0' + arg; + while (a > '9') + b++, a -= 10; + lcd_put(b); + lcd_put(a); +} + +static void puttime(void) +{ + const char * PROGMEM msg; + + lcd_line1(); + puttwo(time.year); + puttwo(time.month); + puttwo(time.day); + lcd_put(' '); + puttwo(time.hour); + puttwo(time.minute); + puttwo(time.second); + + lcd_line2(); + msg = &status[0]; + if (time.year <= 10) + msg = &status[6]; + if (~PINB & (1 << B_SW_FRWD)) + msg = &status[12]; + if (~PINB & (1 << B_SW_BACK)) + msg = &status[18]; + + lcd_puts(msg, 6); + lcd_put(__LPM(&disp[stepstate])); + puttwo(ext_hour); + puttwo(ext_minute); + lcd_put(' '); + puttwo(bootcount / 100); + puttwo(bootcount % 100); +} + +static uint8_t setaccel; + +static void countfwd(void) +{ + cli(); + ext_minute++; + if (ext_minute == 60) { + ext_minute = 0; + ext_hour++; + if (ext_hour == 12) + ext_hour = 0; + } + sei(); +} + +static void step_set(void) +{ + if (ext_minute & 1) { + PORTA &= ~(1 << A_OCPL_A); + } else { + PORTA &= ~(1 << A_OCPL_B); + } +} + +static void step_end(void) +{ + PORTA |= (1 << A_OCPL_A); + PORTA |= (1 << A_OCPL_B); +} + +static void perform(void) +{ + if (waitctr) + return; + + step_end(); + + if (~PINB & (1 << B_SW_BACK)) { + waitctr = setaccel; + if (setaccel > 3) + setaccel--; + cli(); + if (ext_minute) + ext_minute--; + else { + ext_minute = 59; + if (ext_hour) + ext_hour--; + else + ext_hour = 11; + } + sei(); + return; + } + if (~PINB & (1 << B_SW_FRWD)) { + waitctr = setaccel; + if (setaccel > 3) + setaccel--; + countfwd(); + return; + } + setaccel = WAIT; + + if (time.year <= 10) + return; + + PORTA &= ~(1 << PA2); + + uint8_t hbuf, mbuf, hdelta; + + cli(); + hbuf = time.hour; + mbuf = time.minute; + sei(); + + if (hbuf >= 12) + hbuf -= 12; + + switch (stepstate) { + case STEP_INACTIVE: + if (hbuf == ext_hour && mbuf <= ext_minute) + break; + hdelta = 11 + ext_hour - hbuf; + while (hdelta >= 12) + hdelta -=12; + if (hdelta < 3) + break; + countfwd(); + + step_set(); + stepstate = STEP_ACTIVE; + waitctr = WAIT; + break; + case STEP_ACTIVE: + stepstate = STEP_INACTIVE; + waitctr = WAIT; + break; + } +} + +extern void __vectors(void) __attribute__((noreturn)); +__attribute__ ((noreturn)) +SIGNAL (SIG_ANA_COMP) +{ + PORTA = 0xff; + + eeprom_write_byte((void *)EE_HOUR, ext_hour); + eeprom_write_byte((void *)EE_MINUTE, ext_minute); + eeprom_write_byte((void *)EE_CKSUM, ext_hour ^ ext_minute ^ 0xff); + + do + _delay_ms(100); + while (ACSR & (1 << ACO)); + __vectors(); +} int main( void ) { + PORTA = 0xFF; // enable pull ups PORTB = 0xFF; - DDRA |= 1< -#include -#include +#include +#include #include "types.h" -#define XTAL 12000000L +#define XTAL 1000000L // Hardware Definitions -#define MAX7219_DDR DDRB -#define MAX7219_PORT PORTB -#define MAX7219_SCK PB2 -#define MAX7219_DO PB1 -#define MAX7219_STB PB3 - #define DCF77_PIN PINA #define DCF77_PORT PORTA #define DCF77_DDR DDRA -#define DCF77 PA7 +#define DCF77 PA1 diff --git a/max7219.c b/max7219.c deleted file mode 100644 index a1e0da3..0000000 --- a/max7219.c +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************/ -/* */ -/* 7 Segment Driver MAX7219 */ -/* Common Anode Display */ -/* */ -/* Author: Peter Dannegger */ -/* danni@specs.de */ -/* */ -/************************************************************************/ - -#include "main.h" -#include "max7219.h" - -u8 brightness = 5; - -u8 code digits[] = { DIGITS }; - -u8 displaymem[8] = { CHAR_SPACE, // 8 digits, msb first - CHAR_SPACE, - CHAR_SPACE, - CHAR_SPACE, - CHAR_SPACE, - CHAR_SPACE, - CHAR_SPACE, - CHAR_SPACE }; - -u8 code charset[] = { // Definition Character Set - _A+_B+_C+_D+_E+_F , // CHAR_0 - _B+_C , // CHAR_1 - _A+_B+ _D+_E+ _G, // CHAR_2 - _A+_B+_C+_D+ _G, // CHAR_3 - _B+_C+ _F+_G, // CHAR_4 - _A+ _C+_D+ _F+_G, // CHAR_5 - _A+ _C+_D+_E+_F+_G, // CHAR_6 - _A+_B+_C , // CHAR_7 - _A+_B+_C+_D+_E+_F+_G, // CHAR_8 - _A+_B+_C+_D +_F+_G, // CHAR_9 - _A+_B+_C+ _E+_F+_G, // CHAR_A - _C+_D+_E+_F+_G, // CHAR_b - _D+_E+ _G, // CHAR_c ;'c' - _B+_C+_D+_E+ _G, // CHAR_d - _A+ _D+_E+_F+_G, // CHAR_E - _A+ _E+_F+_G, // CHAR_F - 0 , // 16 = SPACE - _G, // 17 = MINUS - _A+_B+ _F+_G, // 18 = GRAD - _A+ _D+_E+_F , // 19 = CHAR_C2 ;'C' - _E+ _G, // 20 = CHAR_r - _C+_D+_E+ _G, // 21 = CHAR_o - _B+_C+ _E+_F+_G, // 22 = H - _D+_E+_F , // 23 = L - _D , // 24 = _ - _A , // 25 = upper "-" - _A+_B+ _E+_F+_G, // CHAR_P - _B+_C+_D+_E+_F , // CHAR_U - _A+_B+_C+ _E+_F // CHAR_M - }; - - -void display_write( u16 dc ) -{ - u8 i; - - MAX7219_DDR |= 1<>= 1; // next segment - dptr++; - } - display_write( byte + i * 256); // output same segments - } -} - - -void display_clear( void ) -{ - u8 i; - - for( i = 8; i; i--) - displaymem[i-1] = CHAR_SPACE; -} - - -void display_init( void ) -{ - display_write( 0xF00 ); // Testmode off - display_write( 0x900 ); // Decode off - display_write( 0xB07 ); // 8 Digits - display_write( 0xC01 ); // Display on - display_write( 0xA00 | brightness ); // Brightness -} - - -void display_off( void ) -{ - display_write( 0xC00 ); -} diff --git a/max7219.h b/max7219.h deleted file mode 100644 index cfbb846..0000000 --- a/max7219.h +++ /dev/null @@ -1,51 +0,0 @@ -/************** Ansteuerung des 7-Segment-Treibers MAX7219 **************/ - -#define BRIGHT 4 // 0 ... 15 - -// Definitionen -// 1. Display type -#define COMMON_CATHODE -//#define COMMON_ANODE // not implemented - -// 2. Pin-Deklaration -//sbit DISCLK = 0x97; //BIT P1.7 -//sbit DISDAT = 0x95; //BIT P1.5 -//sbit DISSTB = 0x94; //BIT P1.4 - -// 3. Segment-Order -#define _A 0x01 // - A - -#define _B 0x40 // | | -#define _C 0x02 // F B -#define _D 0x80 // | | -#define _E 0x08 // - G - -#define _F 0x04 // | | -#define _G 0x10 // E C -#define _DP 0x20 // | | - // - D - P -#define DPBIT 7 - -// 4. Digit-Order -#define DIGITS 8, 128, 4, 16, 1, 32, 2, 64 - -#define CHAR_SPACE 16 -#define CHAR_MINUS 17 -#define CHAR_GRAD 18 -#define CHAR_C2 19 -#define CHAR_R 20 -#define CHAR_O 21 -#define CHAR_H 22 -#define CHAR_L 23 -#define CHAR__ 24 -#define CHAR_S1 25 // upper "-" - - -#define ATTRIB_DP 0x80 // decimal point attribute, must be ored -#define ATTRIB_FLASH 0x40 // flash attribute, must be ored - - -void display_init(void); -void display_out(void); -void display_clear(void); -void display_off(void); - -extern u8 displaymem[]; diff --git a/timebase.c b/timebase.c index 3b97e2b..ee58bf1 100644 --- a/timebase.c +++ b/timebase.c @@ -24,6 +24,7 @@ void timebase_init( void ) TIMSK = 1< +#ifndef _TYPES_H +#define _TYPES_H + +#include typedef unsigned char u8; typedef signed char s8; @@ -21,3 +24,5 @@ typedef signed long s32; #define xdata #define bit uchar + +#endif /* _TYPES_H */ -- cgit v1.2.1