From 7af260dceab82781214ac7fbac9e67e5084d0880 Mon Sep 17 00:00:00 2001 From: Stefan Rupp Date: Sat, 1 Mar 2014 03:50:09 +0100 Subject: [PATCH] init --- .hgignore | 7 ++ Makefile | 41 ++++++++++ lcd.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++ lcd.h | 14 ++++ main.c | 19 +++++ rgbyteclock.c | 15 ++++ rgbyteclock.h | 15 ++++ timer.c | 163 ++++++++++++++++++++++++++++++++++++++++ timer.h | 12 +++ 9 files changed, 489 insertions(+) create mode 100644 .hgignore create mode 100644 Makefile create mode 100644 lcd.c create mode 100644 lcd.h create mode 100644 main.c create mode 100644 rgbyteclock.c create mode 100644 rgbyteclock.h create mode 100644 timer.c create mode 100644 timer.h diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..5d126dc --- /dev/null +++ b/.hgignore @@ -0,0 +1,7 @@ +syntax: glob + +*.o +*.map +*.elf +*.hex + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b53b79f --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +PRG = rgbyteclock +OBJ = rgbyteclock.o timer.o lcd.o main.o +MCU_TARGET = atmega16 +OPTIMIZE = -Os + +DEFS = +LIBS = + +CC = avr-gcc + +override CFLAGS = -g -Wall $(OPTIMIZE) -DF_CPU=16000000UL -std=gnu99 -mmcu=$(MCU_TARGET) $(DEFS) +override LDFLAGS = -Wl,-Map,$(PRG).map + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size -A + + +all: $(PRG).hex + +$(PRG).elf: $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + @echo + @$(SIZE) $@ + @echo + +# dependency: +rgbyteclock.o: timer.o lcd.o rgbyteclock.h +main.o: rgbyteclock.o +timer.o:timer.h +lcd.o: lcd.h + +clean: + rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak + rm -rf *.lst *.map $(EXTRA_CLEAN_FILES) + +hex: $(PRG).hex + +%.hex: %.elf + $(OBJCOPY) -j .text -j .data -O ihex $< $@ + diff --git a/lcd.c b/lcd.c new file mode 100644 index 0000000..1a273aa --- /dev/null +++ b/lcd.c @@ -0,0 +1,203 @@ +/* + * "THE BEER-WARE LICENSE" (Revision 42): + * Martin Wenger and Stefan Rupp + * wrote this file. As long as you retain this notice you can do whatever you want + * with this stuff. If we meet some day, and you think this stuff is worth it, + * you can buy me/us a beer in return. + * (c) 2005-2010 Martin Wenger, Stefan Rupp + * (c) 2014 Stefan Rupp + */ + +#include +#include +#include +#include // ==> _NOP() + +#include "timer.h" +#include "lcd.h" + +#define WAIT_250_ns() _NOP() + +#define LCD_DATA_MODE() (PORTC |= (1<> 4); + _NOP(); + send_nibble(0x0f & byte); +} + + +int lcd_get(void) +{ + lcd_wait_while_busy(); + return lcd_read_byte(1); + +} + +int lcd_put(char c) +{ + lcd_send_byte(c, 1); + return 0; +} + +void lcd_puts(char *s) +{ + while (*s) { + //lcd_put(*s++); + lcd_send_byte(*s++, 1); + } +} + +void lcd_cursor(uint8_t blink) +{ + if (blink) { + // enable display with cursor + blinking + lcd_send_byte(0x0f, 0); + } + else { + // enable display, no cursor, no blinking + lcd_send_byte(0x0c, 0); + return; + } +} + +void lcd_init(void) +{ + /* Initialize both ATmega and Dsiplay + * After return from this function, + * display we be set to 4-bit data mode + */ + + // wait until LCD gets ready to accept instructions. + timer_wait(50); + + // set CONTROL Pins as outputs: + DDRC = 0x3f; + DDRB |= (1< + +void lcd_init(void); +int lcd_put(char c); +void lcd_puts(char *s); +int lcd_get(void); +void lcd_clear(void); +void lcd_locate(uint8_t row, uint8_t column); +void lcd_cursor(uint8_t blink); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..ee0d114 --- /dev/null +++ b/main.c @@ -0,0 +1,19 @@ + + +#include +#include "timer.h" +#include "lcd.h" +#include "rgbyteclock.h" + + +int main(void) +{ + + timer_init(); + lcd_init(); + + rgbyteclock(); + // rgbyteclock() should never end, but who knows... + while (1) { ; } + +} diff --git a/rgbyteclock.c b/rgbyteclock.c new file mode 100644 index 0000000..26c657a --- /dev/null +++ b/rgbyteclock.c @@ -0,0 +1,15 @@ + + +#include "rgbyteclock.h" + + + +void rgbyteclock(void) +{ + + + while(1) { + + } + +} diff --git a/rgbyteclock.h b/rgbyteclock.h new file mode 100644 index 0000000..a71f50a --- /dev/null +++ b/rgbyteclock.h @@ -0,0 +1,15 @@ + +#ifndef RGBYTECLOCK_H +#define RGBYTECLOCK_H + +#include +#include "timer.h" +#include "lcd.h" + + +void rgbyteclock(void); + + + +#endif // RGBYTECLOCK_H + diff --git a/timer.c b/timer.c new file mode 100644 index 0000000..ca9cec2 --- /dev/null +++ b/timer.c @@ -0,0 +1,163 @@ +/* + * "THE BEER-WARE LICENSE" (Revision 42): + * Martin Wenger and Stefan Rupp + * wrote this file. As long as you retain this notice you can do whatever you want + * with this stuff. If we meet some day, and you think this stuff is worth it, + * you can buy me/us a beer in return. + * (c) 2005-2010 Martin Wenger, Stefan Rupp + * (c) 2013,2014 Stefan Rupp + */ + +#include +#include "timer.h" +#include +#include + + +/* timer_time gets increased on every interrupt + * those interrupts happen every 1ms + */ +static volatile uint32_t timer_time; + +ISR(TIMER0_COMP_vect) { + ++timer_time; + return; +} + +/** + * Initialize the timer + * This function has to be called first, before calling timer_wait and/or timer_get, + * else timer_get will always return 0, and timer_wait will wait forever! + */ + +void timer_init(void) +{ + // Stop all interrupts + cli(); + + // Reset timer to zero + timer_time = 0; + + // - Time accuracy: 1 millisecond (corresponding frequency: 1kHz) + // ==> F_CPU = 2Mhz + // ==> 16Mhz / 64 = 250 kHz + // ==> let timer count to 250 to get 1kHz frequency + // therefore: + // - Set Timer/Counter0 prescaler to 64 ==> (1< (1< timer_get() ); + return; +} + +/** + * Decode a integer timestamp (in microseconds) + * into hours, minutes, seconds, microseconds + * \param time the time in microseconds + * \param hours will be filled in to contain the hours after return + * \param minutes will be filled in to contain the minutes after return + * \param seconds will be filled in to contain the seconds after return + * \param ms be filled in to contain the microseconds after return + */ +void timer_decode(uint32_t time, uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint16_t *ms) +{ + if (ms != NULL) { + *ms = time % 1000; + } + time /= 1000; + if (seconds != NULL) { + *seconds = time % 60; + } + time /= 60; + if (minutes != NULL) { + *minutes = time % 60; + } + time /= 60; + if (hours != NULL) { + *hours = time; + } + return; +} + +/** + * Encode a time given as hours, minutes, seconds and microsecods into a integer storing micorseconds + * \param time the variable to store the time into + * \param hour the hours to store + * \param hour the minutes to store + * \param hour the seconds to store + * \param hour the microseconds to store + */ +void timer_encode(uint32_t *time, uint8_t hours, uint8_t minutes, uint8_t seconds, uint16_t ms) +{ + + *time = hours; + *time *= 60; + + *time += minutes; + *time *= 60; + + *time += seconds; + *time *= 1000U; + + *time += ms; + + return; +} + +/* +void timer_validate(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint16_t *ms) +{ + + while (*ms >= 1000) { + *ms -= 1000; + (*seconds)++; + } + + while (*seconds >= 60) { + *ms -= 60; + (*minutes)++; + } + + while (*minutes >= 60) { + *minutes -= 60; + (*hours)++; + } + + return; +} +*/ diff --git a/timer.h b/timer.h new file mode 100644 index 0000000..1015d7b --- /dev/null +++ b/timer.h @@ -0,0 +1,12 @@ +#if !defined __TIMER_H +#define __TIMER_H + +#include + +void timer_wait(uint32_t delay); +uint32_t timer_get(void); +void timer_init(void); +void timer_decode(uint32_t time, uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint16_t *ms); +void timer_encode(uint32_t *time, uint8_t hour, uint8_t minute, uint8_t seconds, uint16_t ms); + +#endif