From: Erik Andresen <erik@vontaene.de> Date: Wed, 6 May 2015 10:10:35 +0000 (+0200) Subject: added initial avr/nano program X-Git-Url: https://defiant.homedns.org/gitweb/?a=commitdiff_plain;h=4053424236542640b1cb23624877725d5ae8e50f;p=ros_wild_thumper.git added initial avr/nano program --- diff --git a/avr/.gitignore b/avr/.gitignore new file mode 100644 index 0000000..9cb13a5 --- /dev/null +++ b/avr/.gitignore @@ -0,0 +1,8 @@ +.dep +*.eep +*.elf +*.lss +*.lst +*.map +*.o +*.sym diff --git a/avr/nano/Makefile b/avr/nano/Makefile new file mode 100644 index 0000000..f8864cc --- /dev/null +++ b/avr/nano/Makefile @@ -0,0 +1,438 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# WinAVR makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + +# mth 2004/09 +# Differences from WinAVR 20040720 sample: +# - DEPFLAGS according to Eric Weddingtion's fix (avrfreaks/gcc-forum) +# - F_OSC Define in CFLAGS and AFLAGS + + +# MCU name +MCU = atmega328p + +# Main Oscillator Frequency +# This is only used to define F_OSC in all assembler and c-sources. +#F_OSC = 3686400 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = main + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c uart.c + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + +# Debugging format. +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. +# AVR (extended) COFF requires stabs, plus an avr-objcopy run. +DEBUG = stabs +#DEBUG = dwarf-2 + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 + +# Place -D or -U options here +CDEFS = -DF_CPU=16000000 + +# Place -I options here +CINCS = -Ii2c/ + + +# Compiler flags. +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g$(DEBUG) +CFLAGS += $(CDEFS) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wstrict-prototypes +CFLAGS += -Wa,-adhlns=$(<:.c=.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) +CFLAGS += -DF_OSC=$(F_OSC) + + + +# Assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs +ASFLAGS += -DF_OSC=$(F_OSC) + + +#Additional libraries. + +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt -lm + +PRINTF_LIB = + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +SCANF_LIB = + +MATH_LIB = -lm + +# External memory options + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + +# Linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(PRINTF_LIB_MIN) $(SCANF_LIB) $(MATH_LIB) + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +#AVRDUDE_PROGRAMMER = avr911 +AVRDUDE_PROGRAMMER = avrisp2 + +# com1 = serial port. Use lpt1 to connect to parallel port. +#AVRDUDE_PORT = /dev/ttyUSB0 # programmer connected to serial device +AVRDUDE_PORT = usb # programmer connected to serial device + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +COPY = cp + + + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + + +# Compiler flags to generate dependency files. +### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d +GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build sizeafter finished end + +build: elf hex eep lss sym + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) .dep/* + + + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program + diff --git a/avr/nano/main.c b/avr/nano/main.c new file mode 100644 index 0000000..0cb0acf --- /dev/null +++ b/avr/nano/main.c @@ -0,0 +1,167 @@ +#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; +} diff --git a/avr/nano/main.hex b/avr/nano/main.hex new file mode 100644 index 0000000..c6b1c2d --- /dev/null +++ b/avr/nano/main.hex @@ -0,0 +1,204 @@ +:100000000C9440000C945D000C945D000C945D0019 +:100010000C945D000C945D000C945D000C945D00EC +:100020000C945D000C945D000C945D000C945D00DC +:100030000C945D000C945D000C945D000C945D00CC +:100040000C945D000C945D000C9401010C945D0017 +:100050000C945D000C945D000C945D000C945D00AC +:100060000C945F000C945D00454647656667002070 +:100070002B2D2E3031323334353637383968000085 +:1000800011241FBECFEFD8E0DEBFCDBF11E0A0E04E +:10009000B1E0EEE9FCE002C005900D92A031B1079D +:1000A000D9F721E0A0E1B1E001C01D92AD38B2075F +:1000B000E1F70E940A020C944D060C9400001F9276 +:1000C0000F920FB60F9211248F939F938091B900D6 +:1000D000887F803879F048F4803609F04DC085EC8F +:1000E0008093BC00109217014FC0883AC1F0883B42 +:1000F000B1F042C080911701882339F08F3F99F504 +:100100008091BB00809316012EC08091BB0080932C +:1001100017018091170181508093170120C08091B1 +:1001200017018230C1F038F48130D9F48091140184 +:100130009091150109C0833019F0843061F011C02D +:1001400080911201909113018093100190931101FD +:100150009093BB0004C0809110018093BB0085EC9C +:1001600003C01092BB0085E88093BC00809117010A +:100170008F5F8093170108C08091BC008B7E8093B5 +:10018000BC0085EC8093BC009F918F910F900FBEB7 +:100190000F901F90189593E890937A0080937C00BD +:1001A00080917C00806C80937C0080917A008064D8 +:1001B00080937A0080917A0086FDFCCF8091780050 +:1001C0009091790045E080E090E020917A002064F1 +:1001D00020937A0020917A0026FDFCCF20917800B0 +:1001E00030917900820F931F415079F720917A0066 +:1001F0002F7720937A0065E070E00E949B03CB018B +:1002000008951F920F920FB60F9211248F939F9310 +:10021000EF93FF938091C00087FF17C0E0911A0110 +:10022000F0911B018091C600808381E0EF37F807D1 +:1002300030F43196F0931B01E0931A0106C08CE173 +:1002400091E090931B0180931A01FF91EF919F9190 +:100250008F910F900FBE0F901F9018959C01E1ECAD +:10026000F0E0808188618083808180688083E2EC17 +:10027000F0E080818660808340E050E084E0220FDF +:10028000331F441F551F8A95D1F760E074E284EF55 +:1002900090E00E94AF03DA01C9010197A109B109F9 +:1002A000892F9A2FAB2FBB27A7FDBA958093C50046 +:1002B00021502093C4008CE191E090931901809328 +:1002C000180190931B0180931A0108952091C0009A +:1002D00025FFFCCFFC0180818093C6000895CF9359 +:1002E000DF931F92CDB7DEB78983CE0101960E94BE +:1002F000660180E090E00F90DF91CF910895CF9359 +:10030000DF93EC01CE012196FC012081222319F01C +:100310000E946601F7CFDF91CF9108958091C000D0 +:1003200087FFFCCF8091C60090E008950C948E0169 +:1003300066E971E08FE691E00C94FB03CF93DF93C5 +:10034000FC01E253FF4FA081B181EC01C453DF4FA8 +:1003500028813981A217B307B9F02091C00025FF89 +:1003600013C02C912093C60020813181AC014553EC +:100370005F4F2417350718F42F5F3F4F03C09C01D0 +:1003800028593F4F31832083E0911801F0911901E2 +:1003900020911A0130911B012E173F07C1F1DC019A +:1003A000AC59BF4FCD91DC911197208128836D917D +:1003B0007C9111979C012B523F4FE9013881EB0151 +:1003C0002881321307C09C012C523F4FE90148811C +:1003D0004F5F48839C012D593F4F6217730728F4E4 +:1003E000EB012196CD93DC9302C08D939C93D1E0D9 +:1003F000EF37FD0730F43196F0931901E0931801BF +:1004000006C08CE191E09093190180931801DF916F +:10041000CF9108951092160180E895E20E942E0176 +:100420000E94980182E58093BA008091BC008B7E87 +:100430008093BC0085EC8093BC0086E091E00E9434 +:10044000780483B7817F83BF7894C0E0D8E180913E +:100450001701833061F08F3F91F08130B9F480E073 +:100460000E94CB0090931501809314010FC081E08E +:100470000E94CB00909313018093120107C08091DA +:100480001601853A19F4F894FE01099583B7816045 +:1004900083BF889583B78E7F83BFD9CF6F927F92BA +:1004A0009F92AF92BF92CF92DF92EF92FF920F9303 +:1004B0001F93CF93DF93CDB7DEB72C970FB6F89489 +:1004C000DEBF0FBECDBF8C017B013A01FC0117825C +:1004D0001682838181FF19C1CE0101965C01F8016A +:1004E000D380F701D3FC2591D3FE21917F012223F4 +:1004F00009F407C1253249F4D3FC2591D3FE21919B +:100500007F01253211F0912C1BC0B801822F90E0A1 +:100510000E94460463013601E2CF222309F4F1C0B0 +:10052000622F70E08FE690E02C870E94F0032C850C +:10053000892B49F0F701D3FC2591D3FE21917F014E +:1005400097FEEBCF0CC0233221F4F92DF0619F2EE2 +:10055000F1CF2C3639F4292D2068922EEBCF2223AF +:1005600009F4CFC0622F70E088E690E02C870E94EB +:10057000F0032C85892B41F06301F4E0CF0ED11CF0 +:10058000B8018FE390E012C0233641F0233789F0A1 +:10059000233521F5F92DF1609F2E0BC0630122E078 +:1005A000C20ED11CB801F301808191810E944604E2 +:1005B000B2CF630122E0C20ED11CF30160807180D2 +:1005C000F30190FC859190FE81913F01882309F40D +:1005D000A2CFB80190E00E944604F2CF243611F079 +:1005E000293639F5630197FE09C0F4E0CF0ED11C1E +:1005F000F30160817181828193810AC0F2E0CF0EA4 +:10060000D11CF30160817181882777FD8095982F37 +:10061000F92DFF7E9F2E97FF09C0909580957095CC +:1006200061957F4F8F4F9F4FF0649F2E2AE030E0FF +:1006300038C02037A1F040F42835D1F02F3609F02A +:1006400060C028E030E019C0253719F0283751F094 +:1006500058C0292D2F7E922E2AE030E00EC0892D21 +:100660008061982E992D9462992E20E130E005C08A +:10067000E92DE4609E2E20E132E0630197FE09C07F +:10068000F4E0CF0ED11CF3016081718182819381EE +:1006900008C0F2E0CF0ED11CF3016081718180E0CF +:1006A00090E0A5010E94A504782E7A1896FE05C058 +:1006B000B8018DE290E00E94460494FE16C0FE014F +:1006C000E70DF11D8081803381F0B80180E390E077 +:1006D0000E94460492FE09C0292D2072822F90E0CC +:1006E000B801885A9F4F0E9446047A94F501E70D9D +:1006F000F11D8081B80190E00E9446047110F5CF91 +:100700000ACFF8018681978102C08FEF9FEF2C9668 +:100710000FB6F894DEBF0FBECDBFDF91CF911F9112 +:100720000F91FF90EF90DF90CF90BF90AF909F9090 +:100730007F906F900895AA1BBB1B51E107C0AA1FB1 +:10074000BB1FA617B70710F0A61BB70B881F991F72 +:100750005A95A9F780959095BC01CD010895052E75 +:1007600097FB1EF400940E94C60357FD07D00E9419 +:10077000CE0307FC03D04EF40C94C603509540956D +:10078000309521953F4F4F4F5F4F0895909580953D +:10079000709561957F4F8F4F9F4F0895A1E21A2E5C +:1007A000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F15 +:1007B000A217B307E407F50720F0A21BB30BE40B65 +:1007C000F50B661F771F881F991F1A9469F76095AC +:1007D0007095809590959B01AC01BD01CF01089566 +:1007E000FC010590061621F00020D9F7C0010895FC +:1007F0003197CF0108950F931F93CF93DF93EC01AF +:100800008B01009731F46115710519F480E090E0D7 +:1008100038C06EE070E081E090E00E940305FC01CA +:100820000097A1F380E883830115110571F0138708 +:10083000028781E883838091830190918401892BD1 +:1008400021F4F0938401E09383012097C9F0D187CC +:10085000C087838182608383809185019091860126 +:10086000892B71F4F0938601E093850180918701D3 +:1008700090918801892B21F4F0938801E0938701FE +:10088000CF01DF91CF911F910F9108950F931F9387 +:10089000CF93DF93182F092FEB018B8181FD03C0CC +:1008A0008FEF9FEF20C082FF10C04E815F812C81AF +:1008B0003D81421753077CF4E881F9819F012F5F46 +:1008C0003F4F39832883108306C0E885F985812F3F +:1008D0000995892B29F72E813F812F5F3F4F3F8359 +:1008E0002E83812F902FDF91CF911F910F9108952B +:1008F0000F931F93CF93DF93E0918501F0918601D1 +:10090000238121FF1BC0EC0100E010E08991609180 +:10091000850170918601DB011896ED91FC91199784 +:10092000882331F00995892B89F30FEF1FEFEECF64 +:100930008AE00995892B11F4C80102C08FEF9FEF5F +:10094000DF91CF911F910F910895FA01AA272830C6 +:1009500051F1203181F1E8946F936E7F6E5F7F4F8C +:100960008F4F9F4FAF4FB1E03ED0B4E03CD0670F08 +:10097000781F891F9A1FA11D680F791F8A1F911D5B +:10098000A11D6A0F711D811D911DA11D20D009F4AB +:1009900068943F912AE0269F11243019305D3193ED +:1009A000DEF6CF010895462F4770405D4193B3E0D6 +:1009B0000FD0C9F7F6CF462F4F70405D4A3318F07D +:1009C000495D31FD4052419302D0A9F7EACFB4E02E +:1009D000A6959795879577956795BA95C9F70097E6 +:1009E0006105710508959B01AC010A2E0694579587 +:1009F000479537952795BA95C9F7620F731F841FDE +:100A0000951FA01D08950F931F93CF93DF93869F8B +:100A10008001879F100D969F100D1124C8010E9420 +:100A20001F05EC01009729F0A80160E070E00E942A +:100A30004606CE01DF91CF911F910F910895CF937C +:100A4000DF938230910510F482E090E0E0918B0119 +:100A5000F0918C0120E030E0A0E0B0E0309739F177 +:100A60004081518148175907B8F04817590771F468 +:100A700082819381109729F013969C938E931297FD +:100A80002CC090938C0180938B0127C021153105D8 +:100A900031F04217530718F0A901DB0101C0EF0143 +:100AA0009A01BD01DF010280F381E02DD7CF21152E +:100AB0003105F9F0281B390B2430310580F48A8187 +:100AC0009B816115710521F0FB019383828304C032 +:100AD00090938C0180938B01FE01329644C0FE01FD +:100AE000E20FF31F819391932250310939832883B8 +:100AF0003AC02091890130918A01232B41F4209141 +:100B000002013091030130938A01209389012091E1 +:100B10000001309101012115310541F42DB73EB797 +:100B20004091040150910501241B350BE09189018E +:100B3000F0918A01E217F307A0F42E1B3F0B281750 +:100B4000390778F0AC014E5F5F4F2417350748F046 +:100B50004E0F5F1F50938A014093890181939193B7 +:100B600002C0E0E0F0E0CF01DF91CF910895CF9394 +:100B7000DF93009709F487C0FC0132971382128239 +:100B8000C0918B01D0918C01209781F4208131811B +:100B9000280F391F8091890190918A01821793074C +:100BA00079F5F0938A01E09389016DC0DE0120E0C0 +:100BB00030E0AE17BF0750F412964D915C91139739 +:100BC0009D014115510509F1DA01F3CFB383A283E9 +:100BD00040815181840F951F8A179B0771F48D9175 +:100BE0009C911197840F951F029691838083129692 +:100BF0008D919C911397938382832115310529F45C +:100C0000F0938C01E0938B013EC0D9011396FC93C5 +:100C1000EE9312974D915D91A40FB51FEA17FB0754 +:100C200079F480819181840F951F0296D9011196E4 +:100C30009C938E938281938113969C938E931297AB +:100C4000E0E0F0E08A819B81009719F0FE01EC0161 +:100C5000F9CFCE01029628813981820F931F20910E +:100C6000890130918A012817390769F4309729F4EE +:100C700010928C0110928B0102C013821282D093C9 +:100C80008A01C0938901DF91CF910895DC0101C0F1 +:0E0C90006D9341505040E0F70895F894FFCF67 +:100C9E0000008D0120000D0A53746172740D000066 +:00000001FF diff --git a/avr/nano/ringbuffer.h b/avr/nano/ringbuffer.h new file mode 100644 index 0000000..ed8b022 --- /dev/null +++ b/avr/nano/ringbuffer.h @@ -0,0 +1,34 @@ +#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 + diff --git a/avr/nano/uart.c b/avr/nano/uart.c new file mode 100644 index 0000000..1a3707a --- /dev/null +++ b/avr/nano/uart.c @@ -0,0 +1,97 @@ +#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; + } +} + diff --git a/avr/nano/uart.h b/avr/nano/uart.h new file mode 100644 index 0000000..1225590 --- /dev/null +++ b/avr/nano/uart.h @@ -0,0 +1,18 @@ +#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 +