--- /dev/null
+.dep
+*.eep
+*.elf
+*.lss
+*.lst
+*.map
+*.o
+*.sym
--- /dev/null
+# Hey Emacs, this is a -*- makefile -*-\r
+#\r
+# WinAVR makefile written by Eric B. Weddington, Jörg Wunsch, et al.\r
+# Released to the Public Domain\r
+# Please read the make user manual!\r
+#\r
+# Additional material for this makefile was submitted by:\r
+# Tim Henigan\r
+# Peter Fleury\r
+# Reiner Patommel\r
+# Sander Pool\r
+# Frederik Rouleau\r
+# Markus Pfaff\r
+#\r
+# On command line:\r
+#\r
+# make all = Make software.\r
+#\r
+# make clean = Clean out built project files.\r
+#\r
+# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).\r
+#\r
+# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio\r
+# 4.07 or greater).\r
+#\r
+# make program = Download the hex file to the device, using avrdude. Please\r
+# customize the avrdude settings below first!\r
+#\r
+# make filename.s = Just compile filename.c into the assembler code only\r
+#\r
+# To rebuild project do "make clean" then "make all".\r
+#\r
+\r
+# mth 2004/09 \r
+# Differences from WinAVR 20040720 sample:\r
+# - DEPFLAGS according to Eric Weddingtion's fix (avrfreaks/gcc-forum)\r
+# - F_OSC Define in CFLAGS and AFLAGS\r
+\r
+\r
+# MCU name\r
+MCU = atmega328p\r
+\r
+# Main Oscillator Frequency\r
+# This is only used to define F_OSC in all assembler and c-sources.\r
+#F_OSC = 3686400\r
+\r
+# Output format. (can be srec, ihex, binary)\r
+FORMAT = ihex\r
+\r
+# Target file name (without extension).\r
+TARGET = main\r
+\r
+\r
+# List C source files here. (C dependencies are automatically generated.)\r
+SRC = $(TARGET).c uart.c\r
+\r
+\r
+# List Assembler source files here.\r
+# Make them always end in a capital .S. Files ending in a lowercase .s\r
+# will not be considered source files but generated files (assembler\r
+# output from the compiler), and will be deleted upon "make clean"!\r
+# Even though the DOS/Win* filesystem matches both .s and .S the same,\r
+# it will preserve the spelling of the filenames, and gcc itself does\r
+# care about how the name is spelled on its command-line.\r
+ASRC = \r
+\r
+\r
+\r
+# Optimization level, can be [0, 1, 2, 3, s]. \r
+# 0 = turn off optimization. s = optimize for size.\r
+# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)\r
+OPT = s\r
+\r
+# Debugging format.\r
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.\r
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.\r
+DEBUG = stabs\r
+#DEBUG = dwarf-2\r
+\r
+# List any extra directories to look for include files here.\r
+# Each directory must be seperated by a space.\r
+EXTRAINCDIRS = \r
+\r
+\r
+# Compiler flag to set the C Standard level.\r
+# c89 - "ANSI" C\r
+# gnu89 - c89 plus GCC extensions\r
+# c99 - ISO C99 standard (not yet fully implemented)\r
+# gnu99 - c99 plus GCC extensions\r
+CSTANDARD = -std=gnu99\r
+\r
+# Place -D or -U options here\r
+CDEFS = -DF_CPU=16000000\r
+\r
+# Place -I options here\r
+CINCS = -Ii2c/\r
+\r
+\r
+# Compiler flags.\r
+# -g*: generate debugging information\r
+# -O*: optimization level\r
+# -f...: tuning, see GCC manual and avr-libc documentation\r
+# -Wall...: warning level\r
+# -Wa,...: tell GCC to pass this to the assembler.\r
+# -adhlns...: create assembler listing\r
+CFLAGS = -g$(DEBUG)\r
+CFLAGS += $(CDEFS) $(CINCS)\r
+CFLAGS += -O$(OPT)\r
+CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums\r
+CFLAGS += -Wall -Wstrict-prototypes\r
+CFLAGS += -Wa,-adhlns=$(<:.c=.lst)\r
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))\r
+CFLAGS += $(CSTANDARD)\r
+CFLAGS += -DF_OSC=$(F_OSC)\r
+\r
+\r
+\r
+# Assembler flags.\r
+# -Wa,...: tell GCC to pass this to the assembler.\r
+# -ahlms: create listing\r
+# -gstabs: have the assembler create line number information; note that\r
+# for use in COFF files, additional information about filenames\r
+# and function names needs to be present in the assembler source\r
+# files -- see avr-libc docs [FIXME: not yet described there]\r
+ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs \r
+ASFLAGS += -DF_OSC=$(F_OSC)\r
+\r
+\r
+#Additional libraries.\r
+\r
+# Minimalistic printf version\r
+PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min\r
+\r
+# Floating point printf version (requires MATH_LIB = -lm below)\r
+PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt -lm\r
+\r
+PRINTF_LIB = \r
+\r
+# Minimalistic scanf version\r
+SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min\r
+\r
+# Floating point + %[ scanf version (requires MATH_LIB = -lm below)\r
+SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt\r
+\r
+SCANF_LIB = \r
+\r
+MATH_LIB = -lm\r
+\r
+# External memory options\r
+\r
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),\r
+# used for variables (.data/.bss) and heap (malloc()).\r
+#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff\r
+\r
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),\r
+# only used for heap (malloc()).\r
+#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff\r
+\r
+EXTMEMOPTS =\r
+\r
+# Linker flags.\r
+# -Wl,...: tell GCC to pass this to linker.\r
+# -Map: create map file\r
+# --cref: add cross reference to map file\r
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref\r
+LDFLAGS += $(EXTMEMOPTS)\r
+LDFLAGS += $(PRINTF_LIB_MIN) $(SCANF_LIB) $(MATH_LIB)\r
+\r
+\r
+\r
+\r
+# Programming support using avrdude. Settings and variables.\r
+\r
+# Programming hardware: alf avr910 avrisp bascom bsd \r
+# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500\r
+#\r
+# Type: avrdude -c ?\r
+# to get a full listing.\r
+#\r
+#AVRDUDE_PROGRAMMER = avr911\r
+AVRDUDE_PROGRAMMER = avrisp2\r
+\r
+# com1 = serial port. Use lpt1 to connect to parallel port.\r
+#AVRDUDE_PORT = /dev/ttyUSB0 # programmer connected to serial device\r
+AVRDUDE_PORT = usb # programmer connected to serial device\r
+\r
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex\r
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep\r
+\r
+\r
+# Uncomment the following if you want avrdude's erase cycle counter.\r
+# Note that this counter needs to be initialized first using -Yn,\r
+# see avrdude manual.\r
+#AVRDUDE_ERASE_COUNTER = -y\r
+\r
+# Uncomment the following if you do /not/ wish a verification to be\r
+# performed after programming the device.\r
+#AVRDUDE_NO_VERIFY = -V\r
+\r
+# Increase verbosity level. Please use this when submitting bug\r
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> \r
+# to submit bug reports.\r
+#AVRDUDE_VERBOSE = -v -v\r
+\r
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)\r
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)\r
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)\r
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)\r
+\r
+\r
+\r
+# ---------------------------------------------------------------------------\r
+\r
+# Define directories, if needed.\r
+DIRAVR = c:/winavr\r
+DIRAVRBIN = $(DIRAVR)/bin\r
+DIRAVRUTILS = $(DIRAVR)/utils/bin\r
+DIRINC = .\r
+DIRLIB = $(DIRAVR)/avr/lib\r
+\r
+\r
+# Define programs and commands.\r
+SHELL = sh\r
+CC = avr-gcc\r
+OBJCOPY = avr-objcopy\r
+OBJDUMP = avr-objdump\r
+SIZE = avr-size\r
+NM = avr-nm\r
+AVRDUDE = avrdude\r
+REMOVE = rm -f\r
+COPY = cp\r
+\r
+\r
+\r
+\r
+# Define Messages\r
+# English\r
+MSG_ERRORS_NONE = Errors: none\r
+MSG_BEGIN = -------- begin --------\r
+MSG_END = -------- end --------\r
+MSG_SIZE_BEFORE = Size before: \r
+MSG_SIZE_AFTER = Size after:\r
+MSG_COFF = Converting to AVR COFF:\r
+MSG_EXTENDED_COFF = Converting to AVR Extended COFF:\r
+MSG_FLASH = Creating load file for Flash:\r
+MSG_EEPROM = Creating load file for EEPROM:\r
+MSG_EXTENDED_LISTING = Creating Extended Listing:\r
+MSG_SYMBOL_TABLE = Creating Symbol Table:\r
+MSG_LINKING = Linking:\r
+MSG_COMPILING = Compiling:\r
+MSG_ASSEMBLING = Assembling:\r
+MSG_CLEANING = Cleaning project:\r
+\r
+\r
+\r
+\r
+# Define all object files.\r
+OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) \r
+\r
+# Define all listing files.\r
+LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)\r
+\r
+\r
+# Compiler flags to generate dependency files.\r
+### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d\r
+GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d\r
+\r
+# Combine all necessary flags and optional flags.\r
+# Add target processor to flags.\r
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)\r
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)\r
+\r
+\r
+\r
+\r
+\r
+# Default target.\r
+all: begin gccversion sizebefore build sizeafter finished end\r
+\r
+build: elf hex eep lss sym\r
+\r
+elf: $(TARGET).elf\r
+hex: $(TARGET).hex\r
+eep: $(TARGET).eep\r
+lss: $(TARGET).lss \r
+sym: $(TARGET).sym\r
+\r
+\r
+\r
+# Eye candy.\r
+# AVR Studio 3.x does not check make's exit code but relies on\r
+# the following magic strings to be generated by the compile job.\r
+begin:\r
+ @echo\r
+ @echo $(MSG_BEGIN)\r
+\r
+finished:\r
+ @echo $(MSG_ERRORS_NONE)\r
+\r
+end:\r
+ @echo $(MSG_END)\r
+ @echo\r
+\r
+\r
+# Display size of file.\r
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex\r
+ELFSIZE = $(SIZE) -A $(TARGET).elf\r
+sizebefore:\r
+ @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi\r
+\r
+sizeafter:\r
+ @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi\r
+\r
+\r
+\r
+# Display compiler version information.\r
+gccversion : \r
+ @$(CC) --version\r
+\r
+\r
+\r
+# Program the device. \r
+program: $(TARGET).hex $(TARGET).eep\r
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)\r
+\r
+\r
+\r
+\r
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.\r
+COFFCONVERT=$(OBJCOPY) --debugging \\r
+--change-section-address .data-0x800000 \\r
+--change-section-address .bss-0x800000 \\r
+--change-section-address .noinit-0x800000 \\r
+--change-section-address .eeprom-0x810000 \r
+\r
+\r
+coff: $(TARGET).elf\r
+ @echo\r
+ @echo $(MSG_COFF) $(TARGET).cof\r
+ $(COFFCONVERT) -O coff-avr $< $(TARGET).cof\r
+\r
+\r
+extcoff: $(TARGET).elf\r
+ @echo\r
+ @echo $(MSG_EXTENDED_COFF) $(TARGET).cof\r
+ $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof\r
+\r
+\r
+\r
+# Create final output files (.hex, .eep) from ELF output file.\r
+%.hex: %.elf\r
+ @echo\r
+ @echo $(MSG_FLASH) $@\r
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@\r
+\r
+%.eep: %.elf\r
+ @echo\r
+ @echo $(MSG_EEPROM) $@\r
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \\r
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@\r
+\r
+# Create extended listing file from ELF output file.\r
+%.lss: %.elf\r
+ @echo\r
+ @echo $(MSG_EXTENDED_LISTING) $@\r
+ $(OBJDUMP) -h -S $< > $@\r
+\r
+# Create a symbol table from ELF output file.\r
+%.sym: %.elf\r
+ @echo\r
+ @echo $(MSG_SYMBOL_TABLE) $@\r
+ $(NM) -n $< > $@\r
+\r
+\r
+\r
+# Link: create ELF output file from object files.\r
+.SECONDARY : $(TARGET).elf\r
+.PRECIOUS : $(OBJ)\r
+%.elf: $(OBJ)\r
+ @echo\r
+ @echo $(MSG_LINKING) $@\r
+ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)\r
+\r
+\r
+# Compile: create object files from C source files.\r
+%.o : %.c\r
+ @echo\r
+ @echo $(MSG_COMPILING) $<\r
+ $(CC) -c $(ALL_CFLAGS) $< -o $@ \r
+\r
+\r
+# Compile: create assembler files from C source files.\r
+%.s : %.c\r
+ $(CC) -S $(ALL_CFLAGS) $< -o $@\r
+\r
+\r
+# Assemble: create object files from assembler source files.\r
+%.o : %.S\r
+ @echo\r
+ @echo $(MSG_ASSEMBLING) $<\r
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@\r
+\r
+\r
+\r
+# Target: clean project.\r
+clean: begin clean_list finished end\r
+\r
+clean_list :\r
+ @echo\r
+ @echo $(MSG_CLEANING)\r
+ $(REMOVE) $(TARGET).hex\r
+ $(REMOVE) $(TARGET).eep\r
+ $(REMOVE) $(TARGET).obj\r
+ $(REMOVE) $(TARGET).cof\r
+ $(REMOVE) $(TARGET).elf\r
+ $(REMOVE) $(TARGET).map\r
+ $(REMOVE) $(TARGET).obj\r
+ $(REMOVE) $(TARGET).a90\r
+ $(REMOVE) $(TARGET).sym\r
+ $(REMOVE) $(TARGET).lnk\r
+ $(REMOVE) $(TARGET).lss\r
+ $(REMOVE) $(OBJ)\r
+ $(REMOVE) $(LST)\r
+ $(REMOVE) $(SRC:.c=.s)\r
+ $(REMOVE) $(SRC:.c=.d)\r
+ $(REMOVE) .dep/*\r
+\r
+\r
+\r
+# Include the dependency files.\r
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)\r
+\r
+\r
+# Listing of phony targets.\r
+.PHONY : all begin finish end sizebefore sizeafter gccversion \\r
+build elf hex eep lss sym coff extcoff \\r
+clean clean_list program\r
+\r
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/sleep.h>
+#include "uart.h"
+
+/*
+ * I2C Register Map (8 Bit)
+ * 0x00 Register select
+ * 0x01 Distance left MSB
+ * 0x02 Distance left LSB
+ * 0x03 Distance right MSB
+ * 0x04 Distance right LSB
+ *
+ * 0xff Bootloader
+ */
+
+
+#define TWI_ACK TWCR = (1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
+#define TWI_RESET TWCR &= ~((1 << TWSTO) | (1 << TWEN)); TWI_ACK
+#define TWI_NAK TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
+
+static volatile uint8_t ireg=0;
+static volatile uint8_t bootloader=0;
+static volatile uint16_t dist_left=0;
+static volatile uint16_t dist_right=0;
+
+ISR(TWI_vect)
+{
+ static int16_t tmp16=0;
+
+ switch (TWSR & 0xF8)
+ {
+ case 0x60: // start write
+ TWI_ACK;
+ ireg = 0;
+ break;
+ case 0x80: // write
+ switch(ireg) {
+ case 0x00: // register select
+ ireg = TWDR;
+ ireg--; // because we do ireg++ below
+ TWI_ACK;
+ break;
+ case 0xff: // bootloader
+ bootloader = TWDR;
+ default:
+ TWI_NAK;
+ }
+ ireg++;
+ break;
+ case 0xA8: // start read
+ case 0xB8: // read
+ switch(ireg) {
+ case 0x01: // Distance left MSB
+ tmp16 = dist_left;
+ TWDR = tmp16>>8;
+ TWI_ACK;
+ break;
+ case 0x02: // Distance right LSB
+ TWDR = tmp16;
+ TWI_ACK;
+ break;
+ case 0x03: // Distance right MSB
+ tmp16 = dist_right;
+ TWDR = tmp16>>8;
+ TWI_ACK;
+ break;
+ case 0x04: // Distance right LSB
+ TWDR = tmp16;
+ TWI_ACK;
+ break;
+ default:
+ TWDR = 0;
+ TWI_NAK;
+ }
+ ireg++;
+ break;
+ default:
+ TWI_RESET;
+ }
+}
+
+
+uint16_t ReadChannel(uint8_t mux) {
+ uint8_t i;
+ uint16_t result;
+
+ ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
+ // setzen auf 8 (1) und ADC aktivieren (1)
+
+ ADMUX = mux; // Kanal waehlen
+ ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
+
+ /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
+ also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
+ ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
+ while ( ADCSRA & (1<<ADSC) ) {
+ // auf Abschluss der Konvertierung warten
+ }
+ result = ADCW; // ADCW muss einmal gelesen werden,
+ // sonst wird Ergebnis der nächsten Wandlung
+ // nicht übernommen.
+
+ /* Eigentliche Messung - Mittelwert aus 5 aufeinanderfolgenden Wandlungen */
+ result = 0;
+ for( i=0; i<5; i++ )
+ {
+ ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
+ while ( ADCSRA & (1<<ADSC) ) {
+ // auf Abschluss der Konvertierung warten
+ }
+ result += ADCW; // Wandlungsergebnisse aufaddieren
+ }
+
+ ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
+
+ result /= 5; // Summe durch 5 teilen = arithm. Mittelwert
+
+ return result;
+}
+
+
+static unsigned short get_distance(uint8_t i) {
+ return ReadChannel(i);
+}
+
+
+int main(void) {
+ bootloader = 0x00;
+ setup_uart(9600);
+ uart_setup_stdout();
+
+ // I2C
+ TWAR = 0x52;
+ TWI_RESET;
+
+ printf("\r\nStart\r\n");
+
+ set_sleep_mode(SLEEP_MODE_IDLE);
+ sei();
+ while(1) {
+ switch(ireg) {
+ case 1: // ir left
+ dist_left = get_distance(0);
+ break;
+ case 3: // ir right
+ dist_right = get_distance(1);
+ break;
+ case 0xff: // Magic reg that starts the bootloader
+ if (bootloader == 0xa5) {
+ cli();
+ {
+ void (*start)(void) = (void*)0x1800;
+ start();
+ }
+ }
+ break;
+ }
+
+ sleep_mode();
+ }
+
+ return 0;
+}
--- /dev/null
+:100000000C9440000C945D000C945D000C945D0019\r
+:100010000C945D000C945D000C945D000C945D00EC\r
+:100020000C945D000C945D000C945D000C945D00DC\r
+:100030000C945D000C945D000C945D000C945D00CC\r
+:100040000C945D000C945D000C9401010C945D0017\r
+:100050000C945D000C945D000C945D000C945D00AC\r
+:100060000C945F000C945D00454647656667002070\r
+:100070002B2D2E3031323334353637383968000085\r
+:1000800011241FBECFEFD8E0DEBFCDBF11E0A0E04E\r
+:10009000B1E0EEE9FCE002C005900D92A031B1079D\r
+:1000A000D9F721E0A0E1B1E001C01D92AD38B2075F\r
+:1000B000E1F70E940A020C944D060C9400001F9276\r
+:1000C0000F920FB60F9211248F939F938091B900D6\r
+:1000D000887F803879F048F4803609F04DC085EC8F\r
+:1000E0008093BC00109217014FC0883AC1F0883B42\r
+:1000F000B1F042C080911701882339F08F3F99F504\r
+:100100008091BB00809316012EC08091BB0080932C\r
+:1001100017018091170181508093170120C08091B1\r
+:1001200017018230C1F038F48130D9F48091140184\r
+:100130009091150109C0833019F0843061F011C02D\r
+:1001400080911201909113018093100190931101FD\r
+:100150009093BB0004C0809110018093BB0085EC9C\r
+:1001600003C01092BB0085E88093BC00809117010A\r
+:100170008F5F8093170108C08091BC008B7E8093B5\r
+:10018000BC0085EC8093BC009F918F910F900FBEB7\r
+:100190000F901F90189593E890937A0080937C00BD\r
+:1001A00080917C00806C80937C0080917A008064D8\r
+:1001B00080937A0080917A0086FDFCCF8091780050\r
+:1001C0009091790045E080E090E020917A002064F1\r
+:1001D00020937A0020917A0026FDFCCF20917800B0\r
+:1001E00030917900820F931F415079F720917A0066\r
+:1001F0002F7720937A0065E070E00E949B03CB018B\r
+:1002000008951F920F920FB60F9211248F939F9310\r
+:10021000EF93FF938091C00087FF17C0E0911A0110\r
+:10022000F0911B018091C600808381E0EF37F807D1\r
+:1002300030F43196F0931B01E0931A0106C08CE173\r
+:1002400091E090931B0180931A01FF91EF919F9190\r
+:100250008F910F900FBE0F901F9018959C01E1ECAD\r
+:10026000F0E0808188618083808180688083E2EC17\r
+:10027000F0E080818660808340E050E084E0220FDF\r
+:10028000331F441F551F8A95D1F760E074E284EF55\r
+:1002900090E00E94AF03DA01C9010197A109B109F9\r
+:1002A000892F9A2FAB2FBB27A7FDBA958093C50046\r
+:1002B00021502093C4008CE191E090931901809328\r
+:1002C000180190931B0180931A0108952091C0009A\r
+:1002D00025FFFCCFFC0180818093C6000895CF9359\r
+:1002E000DF931F92CDB7DEB78983CE0101960E94BE\r
+:1002F000660180E090E00F90DF91CF910895CF9359\r
+:10030000DF93EC01CE012196FC012081222319F01C\r
+:100310000E946601F7CFDF91CF9108958091C000D0\r
+:1003200087FFFCCF8091C60090E008950C948E0169\r
+:1003300066E971E08FE691E00C94FB03CF93DF93C5\r
+:10034000FC01E253FF4FA081B181EC01C453DF4FA8\r
+:1003500028813981A217B307B9F02091C00025FF89\r
+:1003600013C02C912093C60020813181AC014553EC\r
+:100370005F4F2417350718F42F5F3F4F03C09C01D0\r
+:1003800028593F4F31832083E0911801F0911901E2\r
+:1003900020911A0130911B012E173F07C1F1DC019A\r
+:1003A000AC59BF4FCD91DC911197208128836D917D\r
+:1003B0007C9111979C012B523F4FE9013881EB0151\r
+:1003C0002881321307C09C012C523F4FE90148811C\r
+:1003D0004F5F48839C012D593F4F6217730728F4E4\r
+:1003E000EB012196CD93DC9302C08D939C93D1E0D9\r
+:1003F000EF37FD0730F43196F0931901E0931801BF\r
+:1004000006C08CE191E09093190180931801DF916F\r
+:10041000CF9108951092160180E895E20E942E0176\r
+:100420000E94980182E58093BA008091BC008B7E87\r
+:100430008093BC0085EC8093BC0086E091E00E9434\r
+:10044000780483B7817F83BF7894C0E0D8E180913E\r
+:100450001701833061F08F3F91F08130B9F480E073\r
+:100460000E94CB0090931501809314010FC081E08E\r
+:100470000E94CB00909313018093120107C08091DA\r
+:100480001601853A19F4F894FE01099583B7816045\r
+:1004900083BF889583B78E7F83BFD9CF6F927F92BA\r
+:1004A0009F92AF92BF92CF92DF92EF92FF920F9303\r
+:1004B0001F93CF93DF93CDB7DEB72C970FB6F89489\r
+:1004C000DEBF0FBECDBF8C017B013A01FC0117825C\r
+:1004D0001682838181FF19C1CE0101965C01F8016A\r
+:1004E000D380F701D3FC2591D3FE21917F012223F4\r
+:1004F00009F407C1253249F4D3FC2591D3FE21919B\r
+:100500007F01253211F0912C1BC0B801822F90E0A1\r
+:100510000E94460463013601E2CF222309F4F1C0B0\r
+:10052000622F70E08FE690E02C870E94F0032C850C\r
+:10053000892B49F0F701D3FC2591D3FE21917F014E\r
+:1005400097FEEBCF0CC0233221F4F92DF0619F2EE2\r
+:10055000F1CF2C3639F4292D2068922EEBCF2223AF\r
+:1005600009F4CFC0622F70E088E690E02C870E94EB\r
+:10057000F0032C85892B41F06301F4E0CF0ED11CF0\r
+:10058000B8018FE390E012C0233641F0233789F0A1\r
+:10059000233521F5F92DF1609F2E0BC0630122E078\r
+:1005A000C20ED11CB801F301808191810E944604E2\r
+:1005B000B2CF630122E0C20ED11CF30160807180D2\r
+:1005C000F30190FC859190FE81913F01882309F40D\r
+:1005D000A2CFB80190E00E944604F2CF243611F079\r
+:1005E000293639F5630197FE09C0F4E0CF0ED11C1E\r
+:1005F000F30160817181828193810AC0F2E0CF0EA4\r
+:10060000D11CF30160817181882777FD8095982F37\r
+:10061000F92DFF7E9F2E97FF09C0909580957095CC\r
+:1006200061957F4F8F4F9F4FF0649F2E2AE030E0FF\r
+:1006300038C02037A1F040F42835D1F02F3609F02A\r
+:1006400060C028E030E019C0253719F0283751F094\r
+:1006500058C0292D2F7E922E2AE030E00EC0892D21\r
+:100660008061982E992D9462992E20E130E005C08A\r
+:10067000E92DE4609E2E20E132E0630197FE09C07F\r
+:10068000F4E0CF0ED11CF3016081718182819381EE\r
+:1006900008C0F2E0CF0ED11CF3016081718180E0CF\r
+:1006A00090E0A5010E94A504782E7A1896FE05C058\r
+:1006B000B8018DE290E00E94460494FE16C0FE014F\r
+:1006C000E70DF11D8081803381F0B80180E390E077\r
+:1006D0000E94460492FE09C0292D2072822F90E0CC\r
+:1006E000B801885A9F4F0E9446047A94F501E70D9D\r
+:1006F000F11D8081B80190E00E9446047110F5CF91\r
+:100700000ACFF8018681978102C08FEF9FEF2C9668\r
+:100710000FB6F894DEBF0FBECDBFDF91CF911F9112\r
+:100720000F91FF90EF90DF90CF90BF90AF909F9090\r
+:100730007F906F900895AA1BBB1B51E107C0AA1FB1\r
+:10074000BB1FA617B70710F0A61BB70B881F991F72\r
+:100750005A95A9F780959095BC01CD010895052E75\r
+:1007600097FB1EF400940E94C60357FD07D00E9419\r
+:10077000CE0307FC03D04EF40C94C603509540956D\r
+:10078000309521953F4F4F4F5F4F0895909580953D\r
+:10079000709561957F4F8F4F9F4F0895A1E21A2E5C\r
+:1007A000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F15\r
+:1007B000A217B307E407F50720F0A21BB30BE40B65\r
+:1007C000F50B661F771F881F991F1A9469F76095AC\r
+:1007D0007095809590959B01AC01BD01CF01089566\r
+:1007E000FC010590061621F00020D9F7C0010895FC\r
+:1007F0003197CF0108950F931F93CF93DF93EC01AF\r
+:100800008B01009731F46115710519F480E090E0D7\r
+:1008100038C06EE070E081E090E00E940305FC01CA\r
+:100820000097A1F380E883830115110571F0138708\r
+:10083000028781E883838091830190918401892BD1\r
+:1008400021F4F0938401E09383012097C9F0D187CC\r
+:10085000C087838182608383809185019091860126\r
+:10086000892B71F4F0938601E093850180918701D3\r
+:1008700090918801892B21F4F0938801E0938701FE\r
+:10088000CF01DF91CF911F910F9108950F931F9387\r
+:10089000CF93DF93182F092FEB018B8181FD03C0CC\r
+:1008A0008FEF9FEF20C082FF10C04E815F812C81AF\r
+:1008B0003D81421753077CF4E881F9819F012F5F46\r
+:1008C0003F4F39832883108306C0E885F985812F3F\r
+:1008D0000995892B29F72E813F812F5F3F4F3F8359\r
+:1008E0002E83812F902FDF91CF911F910F9108952B\r
+:1008F0000F931F93CF93DF93E0918501F0918601D1\r
+:10090000238121FF1BC0EC0100E010E08991609180\r
+:10091000850170918601DB011896ED91FC91199784\r
+:10092000882331F00995892B89F30FEF1FEFEECF64\r
+:100930008AE00995892B11F4C80102C08FEF9FEF5F\r
+:10094000DF91CF911F910F910895FA01AA272830C6\r
+:1009500051F1203181F1E8946F936E7F6E5F7F4F8C\r
+:100960008F4F9F4FAF4FB1E03ED0B4E03CD0670F08\r
+:10097000781F891F9A1FA11D680F791F8A1F911D5B\r
+:10098000A11D6A0F711D811D911DA11D20D009F4AB\r
+:1009900068943F912AE0269F11243019305D3193ED\r
+:1009A000DEF6CF010895462F4770405D4193B3E0D6\r
+:1009B0000FD0C9F7F6CF462F4F70405D4A3318F07D\r
+:1009C000495D31FD4052419302D0A9F7EACFB4E02E\r
+:1009D000A6959795879577956795BA95C9F70097E6\r
+:1009E0006105710508959B01AC010A2E0694579587\r
+:1009F000479537952795BA95C9F7620F731F841FDE\r
+:100A0000951FA01D08950F931F93CF93DF93869F8B\r
+:100A10008001879F100D969F100D1124C8010E9420\r
+:100A20001F05EC01009729F0A80160E070E00E942A\r
+:100A30004606CE01DF91CF911F910F910895CF937C\r
+:100A4000DF938230910510F482E090E0E0918B0119\r
+:100A5000F0918C0120E030E0A0E0B0E0309739F177\r
+:100A60004081518148175907B8F04817590771F468\r
+:100A700082819381109729F013969C938E931297FD\r
+:100A80002CC090938C0180938B0127C021153105D8\r
+:100A900031F04217530718F0A901DB0101C0EF0143\r
+:100AA0009A01BD01DF010280F381E02DD7CF21152E\r
+:100AB0003105F9F0281B390B2430310580F48A8187\r
+:100AC0009B816115710521F0FB019383828304C032\r
+:100AD00090938C0180938B01FE01329644C0FE01FD\r
+:100AE000E20FF31F819391932250310939832883B8\r
+:100AF0003AC02091890130918A01232B41F4209141\r
+:100B000002013091030130938A01209389012091E1\r
+:100B10000001309101012115310541F42DB73EB797\r
+:100B20004091040150910501241B350BE09189018E\r
+:100B3000F0918A01E217F307A0F42E1B3F0B281750\r
+:100B4000390778F0AC014E5F5F4F2417350748F046\r
+:100B50004E0F5F1F50938A014093890181939193B7\r
+:100B600002C0E0E0F0E0CF01DF91CF910895CF9394\r
+:100B7000DF93009709F487C0FC0132971382128239\r
+:100B8000C0918B01D0918C01209781F4208131811B\r
+:100B9000280F391F8091890190918A01821793074C\r
+:100BA00079F5F0938A01E09389016DC0DE0120E0C0\r
+:100BB00030E0AE17BF0750F412964D915C91139739\r
+:100BC0009D014115510509F1DA01F3CFB383A283E9\r
+:100BD00040815181840F951F8A179B0771F48D9175\r
+:100BE0009C911197840F951F029691838083129692\r
+:100BF0008D919C911397938382832115310529F45C\r
+:100C0000F0938C01E0938B013EC0D9011396FC93C5\r
+:100C1000EE9312974D915D91A40FB51FEA17FB0754\r
+:100C200079F480819181840F951F0296D9011196E4\r
+:100C30009C938E938281938113969C938E931297AB\r
+:100C4000E0E0F0E08A819B81009719F0FE01EC0161\r
+:100C5000F9CFCE01029628813981820F931F20910E\r
+:100C6000890130918A012817390769F4309729F4EE\r
+:100C700010928C0110928B0102C013821282D093C9\r
+:100C80008A01C0938901DF91CF910895DC0101C0F1\r
+:0E0C90006D9341505040E0F70895F894FFCF67\r
+:100C9E0000008D0120000D0A53746172740D000066\r
+:00000001FF\r
--- /dev/null
+#ifndef RINGBUFFER_H
+#define RINGBUFFER_H
+
+#define RINGBUFFER_LEN 100
+#define RINGBUFFER_MAX_NUM 1
+
+typedef struct ringbuffer {
+ char read[RINGBUFFER_LEN];
+ char *in_read_ptr;
+ char *out_read_ptr;
+ char write[RINGBUFFER_LEN];
+ char *in_write_ptr;
+ char *out_write_ptr;
+ FILE *dev;
+ FILE *dev_in_as_out;
+ uint8_t newlines;
+ char block_read;
+} ringbuffer_t;
+
+ringbuffer_t *ringbuffers[RINGBUFFER_MAX_NUM];
+uint8_t num_ringbuffers;
+
+void ringbuffer_setup(FILE *stream, ringbuffer_t *buffer);
+void ringbuffer_setup_in_as_out(FILE *stream, ringbuffer_t *buffer);
+void init_ringbuffers(void);
+void stream_setup(FILE *uart_stream);
+void stream_setup_out_only(FILE *stream);
+void stream_setup_in_as_out(FILE *stream, int ringbuffer_putchar_sound(char, FILE*));
+uint8_t ringbuffer_busy(void);
+void ringbuffer_set_read_noblock(FILE *stream);
+void ringbuffer_set_read_block(FILE *stream, char c);
+
+#endif
+
--- /dev/null
+#include <stdlib.h>
+#include "uart.h"
+#include <avr/interrupt.h>
+
+#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
+
+static volatile char read[RINGBUFFER_LEN];
+static volatile char *in_read_ptr;
+static volatile char *out_read_ptr;
+
+ISR(USART_RX_vect) {
+ // update read from uart
+ if (UCSR0A & (1<<RXC0)) {
+ *in_read_ptr = UDR0;
+
+ if (in_read_ptr < read + RINGBUFFER_LEN - 1) in_read_ptr++;
+ else in_read_ptr = (char *)read;
+ }
+}
+
+
+void setup_uart(unsigned int rate) {
+ UCSR0B |= (1<<TXEN0) | (1<<RXEN0); // UART TX & RX
+ UCSR0B |= (1<<RXCIE0); // RX Interrupt
+ UCSR0C |= (3<<UCSZ00); // Asynchron 8N1
+
+ UBRR0H = (uint8_t)(UART_UBRR_CALC(rate, F_CPU) >> 8);
+ UBRR0L = (uint8_t)UART_UBRR_CALC(rate, F_CPU);
+
+ in_read_ptr = out_read_ptr = read;
+}
+
+
+void uart_putc(char *c) {
+ while (!(UCSR0A & (1<<UDRE0)));
+ UDR0 = *c;
+}
+
+
+int uart_putchar(char c, FILE *stream)
+{
+ uart_putc(&c);
+ return 0;
+}
+
+
+void uart_puts(char *s) {
+ char *c;
+
+ for (c = s; *c != '\0'; c++)
+ uart_putc(c);
+}
+
+
+int uart_getchar(FILE *stream)
+{
+ return uart_getc();
+}
+
+
+int uart_getc() {
+ while (!(UCSR0A & (1<<RXC0)));
+ return UDR0;
+}
+
+
+void uart_setup_stdout() {
+ fdevopen(uart_putchar, uart_getchar);
+}
+
+
+void uart_stream_update(ringbuffer_t *buffer) {
+ // update write to uart
+ if (buffer->out_write_ptr != buffer->in_write_ptr) {
+ if (UCSR0A & (1<<UDRE0)) {
+ UDR0 = *buffer->out_write_ptr;
+ if (buffer->out_write_ptr < buffer->write + RINGBUFFER_LEN - 1) buffer->out_write_ptr++;
+ else buffer->out_write_ptr = buffer->write;
+ }
+ }
+
+ // update read from uart
+ if (in_read_ptr != out_read_ptr) {
+ *buffer->in_read_ptr = *out_read_ptr;
+
+ // update newline chars
+ if (buffer->block_read == *buffer->in_read_ptr) buffer->newlines++;
+
+ if (buffer->in_read_ptr < buffer->read + RINGBUFFER_LEN - 1) buffer->in_read_ptr++;
+ else buffer->in_read_ptr = buffer->read;
+
+ // move pointer
+ if (out_read_ptr < read + RINGBUFFER_LEN - 1) out_read_ptr++;
+ else out_read_ptr = read;
+ }
+}
+
--- /dev/null
+#ifndef UART_H
+#define UART_H
+
+#include <stdio.h>
+#include "ringbuffer.h"
+
+void setup_uart(unsigned int rate);
+void uart_putc(char *c);
+void uart_puts(char *s);
+int uart_getc(void);
+void uart_puti(int i);
+int uart_putchar(char c, FILE *stream);
+int uart_getchar(FILE *stream);
+void uart_setup_stdout(void);
+void uart_stream_update(ringbuffer_t *buffer);
+
+#endif
+