1. John McCombs
  2. arduino-libraries

Commits

John McCombs  committed c7eda0f

- added AVRQueue

  • Participants
  • Parent commits b8fcb2a
  • Branches default

Comments (0)

Files changed (14)

File AVRQueue/AVR/Examples/Makefile

View file
+# Hey Emacs, this is a -*- makefile -*-
+#----------------------------------------------------------------------------
+# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
+#
+# Released to the Public Domain
+#
+# Additional material for this makefile was written by:
+# Peter Fleury
+# Tim Henigan
+# Colin O'Flynn
+# Reiner Patommel
+# Markus Pfaff
+# Sander Pool
+# Frederik Rouleau
+#
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device, using avrdude.
+#                Please customize the avrdude settings below first!
+#
+# make debug = Start either simulavr or avarice as specified for debugging, 
+#              with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+#                   bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
+
+# MCU name
+MCU = atmega168
+AVRDUDEMCU = m168
+
+
+# Processor frequency.
+#     This will define a symbol, F_CPU, in all source code files equal to the 
+#     processor frequency. You can then use this symbol in your source code to 
+#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+#     automatically to create a 32-bit value in your source code.
+F_CPU = 16000000
+
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Target file name (without extension).
+TARGET = basicAvr
+
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = $(TARGET).c ../queue.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 dwarf-2 [default] or stabs.
+#     AVR Studio 4.10 requires dwarf-2.
+#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
+DEBUG = dwarf-2
+
+
+# List any extra directories to look for include files here.
+#     Each directory must be seperated by a space.
+#     Use forward slashes for directory separators.
+#     For a directory that has spaces, enclose it in quotes.
+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=$(F_CPU)UL
+
+
+# Place -I options here
+CINCS =
+
+
+
+#---------------- Compiler Options ----------------
+#  -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)
+
+
+#---------------- Assembler Options ----------------
+#  -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 
+
+
+#---------------- Library Options ----------------
+# 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
+
+# If this is left blank, then it will use the Standard printf version.
+PRINTF_LIB = 
+#PRINTF_LIB = $(PRINTF_LIB_MIN)
+#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
+
+
+# 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
+
+# If this is left blank, then it will use the Standard scanf version.
+SCANF_LIB = 
+#SCANF_LIB = $(SCANF_LIB_MIN)
+#SCANF_LIB = $(SCANF_LIB_FLOAT)
+
+
+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 Options ----------------
+#  -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) $(SCANF_LIB) $(MATH_LIB)
+
+
+
+#---------------- Programming Options (avrdude) ----------------
+
+# 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 = arduino
+
+# com1 = serial port. Use lpt1 to connect to parallel port.
+AVRDUDE_PORT = /dev/ttyUSB0
+
+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 $(AVRDUDEMCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -b 19200
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+
+
+#---------------- Debugging Options ----------------
+
+# For simulavr only - target MCU frequency.
+DEBUG_MFREQ = $(F_CPU)
+
+# Set the DEBUG_UI to either gdb or insight.
+# DEBUG_UI = gdb
+DEBUG_UI = insight
+
+# Set the debugging back-end to either avarice, simulavr.
+DEBUG_BACKEND = avarice
+#DEBUG_BACKEND = simulavr
+
+# GDB Init Filename.
+GDBINIT_FILE = __avr_gdbinit
+
+# When using avarice settings for the JTAG
+JTAG_DEV = /dev/com1
+
+# Debugging port used to communicate between GDB / avarice / simulavr.
+DEBUG_PORT = 4242
+
+# Debugging host used to communicate between GDB / avarice / simulavr, normally
+#     just set to localhost unless doing some sort of crazy debugging when 
+#     avarice is running on a different computer.
+DEBUG_HOST = localhost
+
+
+
+#============================================================================
+
+
+# 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
+WINSHELL = cmd
+
+
+# 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 = $(SRC:.c=.lst) $(ASRC:.S=.lst) 
+
+
+# Compiler flags to generate dependency files.
+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 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)
+
+end:
+	@echo $(MSG_END)
+	@echo
+
+
+# Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
+ELFSIZE = $(SIZE) -A $(TARGET).elf
+AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
+
+sizebefore:
+	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
+	$(AVRMEM) 2>/dev/null; echo; fi
+
+sizeafter:
+	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
+	$(AVRMEM) 2>/dev/null; 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)
+
+
+# Generate avr-gdb config/init file which does the following:
+#     define the reset signal, load the target file, connect to target, and set 
+#     a breakpoint at main().
+gdb-config: 
+	@$(REMOVE) $(GDBINIT_FILE)
+	@echo define reset >> $(GDBINIT_FILE)
+	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
+	@echo end >> $(GDBINIT_FILE)
+	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
+	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
+ifeq ($(DEBUG_BACKEND),simulavr)
+	@echo load  >> $(GDBINIT_FILE)
+endif	
+	@echo break main >> $(GDBINIT_FILE)
+	
+debug: gdb-config $(TARGET).elf
+ifeq ($(DEBUG_BACKEND), avarice)
+	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
+	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
+	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
+	@$(WINSHELL) /c pause
+	
+else
+	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
+	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
+endif
+	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
+	
+
+
+
+# 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) $^ --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 $@
+
+# Create preprocessed source for use in sending a bug report.
+%.i : %.c
+	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ 
+
+
+# Target: clean project.
+clean: begin clean_list end
+
+clean_list :
+	@echo
+	@echo $(MSG_CLEANING)
+	$(REMOVE) $(TARGET).hex
+	$(REMOVE) $(TARGET).eep
+	$(REMOVE) $(TARGET).cof
+	$(REMOVE) $(TARGET).elf
+	$(REMOVE) $(TARGET).map
+	$(REMOVE) $(TARGET).sym
+	$(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 debug gdb-config
+
+

File AVRQueue/AVR/Examples/basicAvr.c

View file
+#include <stdio.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include <stdint.h>
+
+#include "../queue.h"
+
+#define FOSC 16000000
+#define BAUD 9600
+#define MYUBRR FOSC/16/BAUD-1
+
+#define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
+#define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))
+
+#define STATUS_LED 5
+
+void ioinit(void);      // initializes IO
+static int uart_putchar(char c, FILE *stream);
+uint8_t uart_getchar(void);
+
+static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
+
+int testFunction(queue_time_t now)
+{
+    printf("Hello World! Time: %d\r\n", now);
+    return 0;
+}
+
+int testFunction2(queue_time_t now)
+{
+    printf("Stupid World! Time: %d\r\n", now);
+    return 0;
+}
+
+int main (void)
+{	
+    uint32_t x = 0;
+
+    ioinit(); //Setup IO pins and defaults
+
+    scheduleFunction(testFunction, "Test", 3, 3);
+    scheduleFunction(testFunction2, "Test2", 4, 3);
+
+    while(1)
+    {
+
+        scheduleRun(x);
+        x++;
+
+        if(x == 15)
+        {
+            scheduleRemoveFunction("Test2");
+            scheduleChangeFunction("Test", 15, 4);
+        }
+		
+		sbi(PORTB, STATUS_LED);
+		_delay_ms(500);
+
+		cbi(PORTB, STATUS_LED);
+		_delay_ms(500);
+    }
+   
+    return(0);
+}
+
+void ioinit (void)
+{
+    //1 = output, 0 = input
+    DDRB = 0b11101111; //PB4 = MISO 
+    DDRC = 0b11111111; //
+    DDRD = 0b11111110; //PORTD (RX on PD0)
+
+    //USART Baud rate: 9600
+    UBRR0H = MYUBRR >> 8;
+    UBRR0L = MYUBRR;
+    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
+    
+    stdout = &mystdout; //Required for printf init
+}
+
+static int uart_putchar(char c, FILE *stream)
+{
+    //if (c == '\n') uart_putchar('\r', stream);
+  
+    loop_until_bit_is_set(UCSR0A, UDRE0);
+    UDR0 = c;
+    
+    return 0;
+}
+
+uint8_t uart_getchar(void)
+{
+    while( !(UCSR0A & (1<<RXC0)) );
+    return(UDR0);
+}

File AVRQueue/AVR/Tests/Makefile

View file
+# Hey Emacs, this is a -*- makefile -*-
+#----------------------------------------------------------------------------
+# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
+#
+# Released to the Public Domain
+#
+# Additional material for this makefile was written by:
+# Peter Fleury
+# Tim Henigan
+# Colin O'Flynn
+# Reiner Patommel
+# Markus Pfaff
+# Sander Pool
+# Frederik Rouleau
+#
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device, using avrdude.
+#                Please customize the avrdude settings below first!
+#
+# make debug = Start either simulavr or avarice as specified for debugging, 
+#              with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+#                   bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
+
+# MCU name
+MCU = atmega168
+AVRDUDEMCU = m168
+
+
+# Processor frequency.
+#     This will define a symbol, F_CPU, in all source code files equal to the 
+#     processor frequency. You can then use this symbol in your source code to 
+#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+#     automatically to create a 32-bit value in your source code.
+F_CPU = 16000000
+
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Target file name (without extension).
+TARGET = avrTests
+
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = $(TARGET).c tests.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 dwarf-2 [default] or stabs.
+#     AVR Studio 4.10 requires dwarf-2.
+#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
+DEBUG = dwarf-2
+
+
+# List any extra directories to look for include files here.
+#     Each directory must be seperated by a space.
+#     Use forward slashes for directory separators.
+#     For a directory that has spaces, enclose it in quotes.
+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=$(F_CPU)UL
+
+
+# Place -I options here
+CINCS =
+
+
+
+#---------------- Compiler Options ----------------
+#  -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)
+
+
+#---------------- Assembler Options ----------------
+#  -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 
+
+
+#---------------- Library Options ----------------
+# 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
+
+# If this is left blank, then it will use the Standard printf version.
+PRINTF_LIB = 
+#PRINTF_LIB = $(PRINTF_LIB_MIN)
+#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
+
+
+# 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
+
+# If this is left blank, then it will use the Standard scanf version.
+SCANF_LIB = 
+#SCANF_LIB = $(SCANF_LIB_MIN)
+#SCANF_LIB = $(SCANF_LIB_FLOAT)
+
+
+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 Options ----------------
+#  -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) $(SCANF_LIB) $(MATH_LIB)
+
+
+
+#---------------- Programming Options (avrdude) ----------------
+
+# 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 = arduino
+
+# com1 = serial port. Use lpt1 to connect to parallel port.
+AVRDUDE_PORT = /dev/ttyUSB0
+
+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 $(AVRDUDEMCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -b 19200
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+
+
+#---------------- Debugging Options ----------------
+
+# For simulavr only - target MCU frequency.
+DEBUG_MFREQ = $(F_CPU)
+
+# Set the DEBUG_UI to either gdb or insight.
+# DEBUG_UI = gdb
+DEBUG_UI = insight
+
+# Set the debugging back-end to either avarice, simulavr.
+DEBUG_BACKEND = avarice
+#DEBUG_BACKEND = simulavr
+
+# GDB Init Filename.
+GDBINIT_FILE = __avr_gdbinit
+
+# When using avarice settings for the JTAG
+JTAG_DEV = /dev/com1
+
+# Debugging port used to communicate between GDB / avarice / simulavr.
+DEBUG_PORT = 4242
+
+# Debugging host used to communicate between GDB / avarice / simulavr, normally
+#     just set to localhost unless doing some sort of crazy debugging when 
+#     avarice is running on a different computer.
+DEBUG_HOST = localhost
+
+
+
+#============================================================================
+
+
+# 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
+WINSHELL = cmd
+
+
+# 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 = $(SRC:.c=.lst) $(ASRC:.S=.lst) 
+
+
+# Compiler flags to generate dependency files.
+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 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)
+
+end:
+	@echo $(MSG_END)
+	@echo
+
+
+# Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
+ELFSIZE = $(SIZE) -A $(TARGET).elf
+AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
+
+sizebefore:
+	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
+	$(AVRMEM) 2>/dev/null; echo; fi
+
+sizeafter:
+	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
+	$(AVRMEM) 2>/dev/null; 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)
+
+
+# Generate avr-gdb config/init file which does the following:
+#     define the reset signal, load the target file, connect to target, and set 
+#     a breakpoint at main().
+gdb-config: 
+	@$(REMOVE) $(GDBINIT_FILE)
+	@echo define reset >> $(GDBINIT_FILE)
+	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
+	@echo end >> $(GDBINIT_FILE)
+	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
+	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
+ifeq ($(DEBUG_BACKEND),simulavr)
+	@echo load  >> $(GDBINIT_FILE)
+endif	
+	@echo break main >> $(GDBINIT_FILE)
+	
+debug: gdb-config $(TARGET).elf
+ifeq ($(DEBUG_BACKEND), avarice)
+	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
+	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
+	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
+	@$(WINSHELL) /c pause
+	
+else
+	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
+	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
+endif
+	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
+	
+
+
+
+# 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) $^ --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 $@
+
+# Create preprocessed source for use in sending a bug report.
+%.i : %.c
+	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ 
+
+
+# Target: clean project.
+clean: begin clean_list end
+
+clean_list :
+	@echo
+	@echo $(MSG_CLEANING)
+	$(REMOVE) $(TARGET).hex
+	$(REMOVE) $(TARGET).eep
+	$(REMOVE) $(TARGET).cof
+	$(REMOVE) $(TARGET).elf
+	$(REMOVE) $(TARGET).map
+	$(REMOVE) $(TARGET).sym
+	$(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 debug gdb-config
+
+

File AVRQueue/AVR/Tests/avrTests.c

View file
+#include <stdio.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include <stdint.h>
+
+#include "../queue.h"
+
+#include "tests.h"
+
+#define FOSC 16000000
+#define BAUD 9600
+#define MYUBRR FOSC/16/BAUD-1
+
+#define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
+#define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))
+
+#define STATUS_LED 5
+
+void ioinit(void);      // initializes IO
+static int uart_putchar(char c, FILE *stream);
+uint8_t uart_getchar(void);
+
+static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
+
+int main (void)
+{   
+    uint32_t x = 0;
+
+    ioinit(); //Setup IO pins and defaults
+
+    printf("Tests Starting.\r\n");
+
+   
+    return(0);
+}
+
+void ioinit (void)
+{
+    //1 = output, 0 = input
+    DDRB = 0b11101111; //PB4 = MISO 
+    DDRC = 0b11111111; //
+    DDRD = 0b11111110; //PORTD (RX on PD0)
+
+    //USART Baud rate: 9600
+    UBRR0H = MYUBRR >> 8;
+    UBRR0L = MYUBRR;
+    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
+    
+    stdout = &mystdout; //Required for printf init
+}
+
+static int uart_putchar(char c, FILE *stream)
+{
+    //if (c == '\n') uart_putchar('\r', stream);
+  
+    loop_until_bit_is_set(UCSR0A, UDRE0);
+    UDR0 = c;
+    
+    return 0;
+}
+
+uint8_t uart_getchar(void)
+{
+    while( !(UCSR0A & (1<<RXC0)) );
+    return(UDR0);
+}

File AVRQueue/AVR/Tests/tests.c

View file
+#include <util/delay.h>
+#include <stdio.h>
+
+#include "../queue.c"
+
+#include "tests.h"
+
+int testFunction(queue_time_t now)
+{
+    _delay_ms(100);
+    return 1;
+}
+
+int test_addTooMany(void)
+{
+   int rv;
+   int testStatus = 0;
+   rv = scheduleFunction(testFunction, "Test1", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test2", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test3", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test4", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test5", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test6", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test7", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test8", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test9", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test10", 5000, 1000);
+   if(rv != 0)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = scheduleFunction(testFunction, "Test11", 5000, 1000);
+   if(rv != -1)
+   {
+     printf("test_addTooMany failed.");
+     testStatus = -1;
+   }
+
+   return testStatus;
+}
+int test_removeNonExistent(void)
+{
+    int rv;
+    int testStatus = 0;
+    rv = scheduleFunction(testFunction, "Test", 5000, 1000);
+    if(rv != 0)
+    {
+      printf("test_removeNonExistent failed.");
+      testStatus = -1;
+    }
+    rv = scheduleRemoveFunction("Fail");
+    if(rv != -1)
+    {
+      printf("test_removeNonExistent failed.");
+      testStatus = -1;
+    }
+    return testStatus;
+}
+
+int test_tooManyCharacters(void)
+{
+    int rv;
+    int testStatus = 0;
+    rv = scheduleFunction(testFunction, "ReallyLongName", 5000, 1000);
+    if(rv != -1)
+    {
+      printf("test_tooManyCharacters failed.");
+      testStatus = -1;
+    }
+    return testStatus;
+}
+
+int test_changeNonExistent(void)
+{
+    int rv;
+    int testStatus = 0;
+    rv = scheduleFunction(testFunction, "Test", 5000, 1000);
+    if(rv != 0)
+    {
+      printf("test_changeNonExistent failed.");
+      testStatus = -1;
+    }
+    rv = scheduleChangeFunction("Fail", 1000, 1000);
+    if(rv != -1)
+    {
+      printf("test_changeNonExistent failed.");
+      testStatus = -1;
+    }
+    return testStatus;
+}
+
+int test_runEmpty(void)
+{
+    int rv = 0;
+    int testStatus = 0;
+    rv = scheduleRun(10);
+    if (rv != -1)
+    {
+      printf("test_runEmpty failed.");
+      testStatus = -1;
+    }
+    return testStatus;
+}
+
+int testAll(void)
+{
+    queueStart = 0;
+    queueEnd = 0;
+    int testStatus = 0;
+    testStatus |= test_addTooMany();
+    queueStart = 0;
+    queueEnd = 0;
+    testStatus |= test_removeNonExistent();
+    queueStart = 0;
+    queueEnd = 0;
+    testStatus |= test_tooManyCharacters();
+    queueStart = 0;
+    queueEnd = 0;
+    testStatus |= test_changeNonExistent();
+    queueStart = 0;
+    queueEnd = 0;
+    testStatus |= test_runEmpty();
+
+    return testStatus;
+
+
+}

File AVRQueue/AVR/Tests/tests.h

View file
+#ifndef TESTS_H
+#define TESTS_H
+
+int test_addTooMany(void);
+int test_removeNonExistent(void);
+int test_tooManyCharacters(void);
+int test_changeNonExistent(void);
+int test_runEmpty(void);
+
+int testAll(void);
+
+#endif

File AVRQueue/AVR/queue.c

View file
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "queue.h"
+
+static uint8_t queueStart = 0;
+static uint8_t queueEnd = 0;
+static uint8_t itemsInQueue = 0;
+
+static queueItem scheduleQueue[QUEUE_DEPTH];
+
+static int scheduleQueueGetTop(queueItem *returnItem);
+static int internalScheduleFunction(queueItem pItem);
+
+int scheduleFunction(queuedFunction pFunction, const char *pId, queue_time_t pInitialRun, queue_time_t pRecur)
+{
+    int rv = 0;
+
+    queueItem newItem;
+    newItem.fPtr = pFunction;
+    memset(newItem.itemName, 0, NAME_LIMIT);
+    memcpy(newItem.itemName, pId, strlen(pId));
+    newItem.recur = pRecur;
+    newItem.next = pInitialRun;
+
+    rv = internalScheduleFunction(newItem);
+
+    return rv;
+}
+
+int scheduleRemoveFunction(const char *pId)
+{
+    queueItem target;
+    int rv = 0;
+    for (int i = 0; i < itemsInQueue; ++i)
+    {
+        if(scheduleQueueGetTop(&target) == 0)
+        {
+            if(strcmp(target.itemName, pId) != 0)
+            {
+                internalScheduleFunction(target);
+            }
+        } else {
+            rv = -1;
+            break;
+        }
+    }
+
+    return rv;
+}
+
+int scheduleChangeFunction(const char *pId, queue_time_t pNewNext, queue_time_t pNewRecur)
+{
+    queueItem target;
+    int rv = 0;
+    for (int i = 0; i < itemsInQueue; ++i)
+    {
+        if(scheduleQueueGetTop(&target) == 0)
+        {
+            if(strcmp(target.itemName, pId) == 0)
+            {
+                target.next = pNewNext;
+                target.recur = pNewRecur;
+            }
+            internalScheduleFunction(target);
+        } else {
+            rv = -1;
+            break;
+        }
+    }
+
+    return rv;
+}
+
+int scheduleRun(queue_time_t pNow)
+{
+    queueItem target;
+    int rv = 0;
+    for (int i = 0; i < itemsInQueue; ++i)
+    {
+        if(scheduleQueueGetTop(&target)==0)
+        {
+            if(target.next <= pNow)
+            {
+                int tRv;
+                tRv = (target.fPtr)(pNow);
+                if(tRv == 0)
+                {
+                    rv++;
+                }
+                if(target.recur != 0)
+                {
+                    target.next = pNow + target.recur;
+                    internalScheduleFunction(target);
+                }
+            } else {
+                internalScheduleFunction(target);
+            }
+        } else {
+            rv = -1;
+            break;
+        }
+    }
+
+    return rv;
+}
+
+static int scheduleQueueGetTop(queueItem *returnItem)
+{
+    int rv = 0;
+    //Remove the top item, stuff it into returnItem
+    if (queueEnd != queueStart) {
+            queueItem tempQueueItem = scheduleQueue[queueStart];
+            //This Algorithm also from Wikipedia.
+            queueStart = (queueStart + 1) % QUEUE_DEPTH;
+            *returnItem = tempQueueItem;
+            itemsInQueue--;
+    } else {
+    //if the buffer is empty, return an error code
+        rv = -1;
+    }
+
+    return rv;   
+}
+
+static int internalScheduleFunction(queueItem pItem)
+{
+    int rv = 0;
+    if ((queueEnd + 1) % QUEUE_DEPTH != queueStart) {
+        scheduleQueue[queueEnd] = pItem;
+        queueEnd = (queueEnd + 1) % QUEUE_DEPTH;
+        itemsInQueue++;
+    } else {
+        rv = -1;
+    }
+    return rv;
+}

File AVRQueue/AVR/queue.h

View file
+#ifndef QUEUE_H
+#define QUEUE_H
+
+// Settings
+#define QUEUE_DEPTH 10
+#define NAME_LIMIT 8
+typedef uint32_t queue_time_t;
+
+typedef int (*queuedFunction)(queue_time_t);
+
+typedef struct _queue_item
+{
+    queuedFunction fPtr;
+    queue_time_t recur;
+    queue_time_t next;
+    char itemName[NAME_LIMIT];
+} queueItem;
+
+//Functions
+int scheduleFunction(queuedFunction, const char *, queue_time_t, queue_time_t);
+int scheduleRemoveFunction(const char *);
+int scheduleChangeFunction(const char *, queue_time_t, queue_time_t);
+
+int scheduleRun(queue_time_t);
+
+#endif

File AVRQueue/Arduino/Examples/example.ino

View file
+#include <Queue.h>
+
+void setup() {
+    pinMode(13, OUTPUT);
+    Serial.begin(9600);
+    Serial.println("Alive");
+
+    Queue myQueue;
+    myQueue.scheduleFunction(testFunction, "Test", 5000, 1000);
+
+    while(1) {
+        myQueue.Run(millis());
+        delay(10);
+    }
+}
+
+int testFunction(unsigned long now)
+{
+    Serial.print("Hello: ");
+    Serial.println(now);
+}
+
+void loop() {
+}

File AVRQueue/Arduino/Queue.cpp

View file
+#include "Queue.h"
+
+Queue::Queue()
+{
+    _itemsInQueue = 0;
+    _queueStart = 0;
+    _queueEnd = 0;
+}
+
+int Queue::scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur)
+{
+	int rv = 0;
+
+    if(strlen(id) > 7)
+    {
+        rv = -1;
+    } else {
+
+    	queueItem newItem;
+    	newItem.fPtr = func;
+    	memset(newItem.itemName, 0, 8);
+    	memcpy(newItem.itemName, id, strlen(id));
+    	newItem.recur = recur;
+    	newItem.next = initialRun;
+
+    	rv = _addToQueue(newItem);
+    }
+
+	return rv;
+}
+
+int Queue::scheduleRemoveFunction(const char * id)
+{
+	queueItem target;
+    int rv = -1;
+    for (int i = 0; i < _itemsInQueue; ++i)
+    {
+        if(_queueGetTop(target) == 0)
+        {
+            if(strcmp(target.itemName, id) == 0)
+            {
+                rv = 0;
+            } else {
+                _addToQueue(target);
+            }
+        } else {
+            rv = -1;
+            break;
+        }
+    }
+
+    return rv;
+}
+
+int Queue::scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur)
+{
+	queueItem target;
+    int rv = -1;
+    for (int i = 0; i < _itemsInQueue; ++i)
+    {
+        if(_queueGetTop(target) == 0)
+        {
+            if(strcmp(target.itemName, id) == 0)
+            {
+                target.next = nextRunTime;
+                target.recur = newRecur;
+                rv = 0;
+            }
+            _addToQueue(target);
+        } else {
+            rv = -1;
+            break;
+        }
+    }
+
+    return rv;
+}
+
+int Queue::Run(unsigned long now)
+{
+	queueItem target;
+    int rv = 0;
+    if(_itemsInQueue == 0)
+    {
+        rv = -1;
+    }
+    for (int i = 0; i < _itemsInQueue; ++i)
+    {
+        if(_queueGetTop(target)==0)
+        {
+            if(target.next <= now)
+            {
+                int tRv;
+                tRv = (target.fPtr)(now);
+                if(tRv == 0)
+                {
+                    rv++;
+                }
+                if(target.recur != 0)
+                {
+                    target.next = now + target.recur;
+                    _addToQueue(target);
+                }
+            } else {
+                _addToQueue(target);
+            }
+        } else {
+            rv = -1;
+            break;
+        }
+    }
+
+    return rv;
+}
+
+int Queue::_queueGetTop(queueItem &item)
+{
+	int rv = 0;
+    //Remove the top item, stuff it into item
+    if (_queueEnd != _queueStart) {
+            queueItem tempQueueItem = _schedule[_queueStart];
+            //This Algorithm also from Wikipedia.
+            _queueStart = (_queueStart + 1) % QueueScheduleSize;
+            item = tempQueueItem;
+            _itemsInQueue--;
+    } else {
+    //if the buffer is empty, return an error code
+        rv = -1;
+    }
+
+    return rv;  
+}
+
+int Queue::_addToQueue(queueItem item)
+{
+	//This is just a circular buffer, and this algorithm is stolen from wikipedia
+	int rv = 0;
+    if ((_queueEnd + 1) % QueueScheduleSize != _queueStart) {
+        _schedule[_queueEnd] = item;
+        _queueEnd = (_queueEnd + 1) % QueueScheduleSize;
+        _itemsInQueue++;
+    } else {
+        //if buffer is full, error
+        rv = -1;
+    }
+    return rv;
+}

File AVRQueue/Arduino/Queue.h

View file
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include "Arduino.h"
+
+typedef int (*queuedFunction)(unsigned long);
+
+#define QueueScheduleSize 11
+
+struct queueItem {
+	queuedFunction fPtr;
+	unsigned long next;
+	unsigned long recur;
+	char itemName[8];
+};
+
+class Queue
+{
+private:
+	unsigned int _queueStart;
+	unsigned int _queueEnd;
+	unsigned int _itemsInQueue;
+	queueItem _schedule[QueueScheduleSize];
+
+	int _queueGetTop(queueItem &item);
+	int _addToQueue(queueItem item);
+
+public:
+	Queue();
+
+	int scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur);
+	int scheduleRemoveFunction(const char * id);
+	int scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur);
+
+	int Run(unsigned long now);
+	/* data */
+};
+
+#endif

File AVRQueue/Arduino/Tests/arduinoTests.ino

View file
+#include <Queue.h>
+
+/*
+  Blink
+  Turns on an LED on for one second, then off for one second, repeatedly.
+ 
+  This example code is in the public domain.
+ */
+
+void setup() {                
+  // initialize the digital pin as an output.
+  // Pin 13 has an LED connected on most Arduino boards:
+  pinMode(13, OUTPUT);     
+  Serial.begin(9600);
+  Serial.println("Alive");
+
+  int testStatus = 0;
+  testStatus |= test_addTooMany();
+  testStatus |= test_removeNonExistent();
+  testStatus |= test_tooManyCharacters();
+  testStatus |= test_changeNonExistent();
+  testStatus |= test_runEmpty();
+
+  if(testStatus == 0)
+  {
+    Serial.println("All tests passed.");
+  } else {
+    Serial.println("Something Failed.");
+  }
+  
+}
+
+void loop() {
+  delay(1000);
+}
+
+int testFunction(unsigned long now)
+{
+  Serial.print("Hello: ");
+  Serial.print(now);
+  Serial.println();
+}
+
+int test_addTooMany(void)
+{
+   Queue testQueue;
+   int rv;
+   int testStatus = 0;
+   rv = testQueue.scheduleFunction(testFunction, "Test1", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test2", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test3", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test4", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test5", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test6", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test7", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test8", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test9", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test10", 5000, 1000);
+   if(rv != 0)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+   rv = testQueue.scheduleFunction(testFunction, "Test11", 5000, 1000);
+   if(rv != -1)
+   {
+     Serial.println("test_addTooMany failed.");
+     testStatus = -1;
+   }
+
+   return testStatus;
+}
+
+int test_removeNonExistent(void)
+{
+  Queue testQueue;
+  int rv;
+  int testStatus = 0;
+  rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000);
+  if(rv != 0)
+  {
+    Serial.println("test_removeNonExistent failed.");
+    testStatus = -1;
+  }
+  rv = testQueue.scheduleRemoveFunction("Fail");
+  if(rv != -1)
+  {
+    Serial.println("test_removeNonExistent failed.");
+    testStatus = -1;
+  }
+  return testStatus;
+}
+
+int test_tooManyCharacters(void)
+{
+  Queue testQueue;
+  int rv;
+  int testStatus = 0;
+  rv = testQueue.scheduleFunction(testFunction, "ReallyLongName", 5000, 1000);
+  if(rv != -1)
+  {
+    Serial.println("test_tooManyCharacters failed.");
+    testStatus = -1;
+  }
+  return testStatus;
+}
+
+int test_changeNonExistent(void)
+{
+  Queue testQueue;
+  int rv;
+  int testStatus = 0;
+  rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000);
+  if(rv != 0)
+  {
+    Serial.println("test_changeNonExistent failed.");
+    testStatus = -1;
+  }
+  rv = testQueue.scheduleChangeFunction("Fail", 1000, 1000);
+  if(rv != -1)
+  {
+    Serial.println("test_changeNonExistent failed.");
+    testStatus = -1;
+  }
+  return testStatus;
+}
+
+int test_runEmpty(void)
+{
+  Queue myQueue;
+  int rv = 0;
+  int testStatus = 0;
+  rv = myQueue.Run(10);
+  if (rv != -1)
+  {
+    Serial.println("test_runEmpty failed.");
+    testStatus = -1;
+  }
+  return testStatus;
+}

File AVRQueue/COPYING

View file
+Copyright (c) 2012 Brad Luyster
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File AVRQueue/README.md

View file
+AVRQueue
+========
+
+AVRQueue is a task queuing library for AVR and Arduino processors.  Included here are two different branches, **AVR** and **Arduino**.
+
+This is a simple queuing library.  Add functions to the queue, along with a unique identifier, an initial run time, and a recurrence time.  If your time scale is in seconds, an item with an initial run time of 1, and a recurrence of 5 will run after time 1 second, and every 5 seconds thereafter.
+
+Functions are not guaranteed to execute deterministic when they're scheduled.  This is a very primitive library.  The run function simply waits for a function in the queue to reach its run time, runs the function, then continues through the queue.  If queued functions take a very long time to execute, then functions may not execute precisely when desired.  For this reason, a "now" variable is passed into every function in order to let it know when it actually runs.
+
+AVR
+---
+
+The AVR library is oriented towards enthusiasts.  Compile **queue.c** with your project, and include **queue.h** in any files that need to add, modify, remove, or execute functions from the queue.
+
+All settings are in **queue.h**:
+
+* ***QUEUE_DEPTH***:  The number of functions that you can store in the queue.  More functions = more RAM required. (_Default:_ 10)
+
+* ***NAME_LIMIT***: The number of characters used to store unique IDs for tasks. (_Default:_ 8)
+
+* ***queue_time_t***: Typedef for the storage of timing data.  Use the native type for whatever time system you're using. (If you're using AVR timers, change this to uint_16t). (_Default:_ uint_32t)
+
+### Usage
+
+* ***Queued Functions***: All queued functions must have the following C signature:
+> int queued\_function(queue\_time\_t now)<br />
+> The _now_ variable will contain the time the function was called.
+
+* int scheduleFunction(queuedFunction **pFunction**, const char ***pId**, queue\_time\_t **pInitialRun**, queue\_time\_t **pRecur**)
+> Add a function to the queue.<br/>
+> ***Return Values:***<br/>
+>> **0** if successful.<br/>
+>> **-1** if unsuccessful (queue is full).<br/>
+
+ * **pFunction**: Function to put in the queue.
+ * ***pId**: Up to 8 character unique identifier. (Unless you change the length).
+ * **pInitialRun**: Initial run time, in whatever time units you feed into **run**.
+ * **pRecur**: Recurrence period, in whatever time units you feed into **run**.
+
+* int scheduleRemoveFunction(const char ***pId**)
+> Remove a function with given unique ID from the queue.<br />
+> ***Return Values:***<br/>
+>> **0** if successful. <br/>
+>> **-1** if unsuccessful.
+
+ * ***pId**: Unique id 
+
+* int scheduleChangeFunction(const char ***pId**, queue_time_t **pNewNext**, queue_time_t **pNewRecur**)
+> Change function in the queue.<br/>
+> ***Return Values:***<br/>
+>> **0** if successful. <br/>
+>> **-1** if unsuccessful.
+
+ * ***pId**: Unique identifier.
+ * **pNewNext**: Next time to run the function.
+ * **pNewRecur**: New recurrence time.
+
+* int scheduleRun(queue_time_t **pNow**)
+> Run all the queued items.  Run this in a loop to execute the queue.<br/>
+> ***Return Values:***<br/>
+>> **-1** if unsuccessful.
+>> **Number of queue items successfully ran** otherwise.
+
+ * **pNow**: the current time.
+
+Arduino
+-------
+
+The Arduino library is much easier to use.  Extract to <Arduino Root>/Libraries/Queue/, restart the IDE, and start using.
+
+* Maximum of 10 items in the queue.
+* Unique IDs are up to 8 characters, no more.
+* Use with ```millis();```
+
+### Usage
+
+* ***Queued Functions***: All queued functions must have a C signature (either not class-members, or static class-members) of:
+> int queued\_function(unsigned long now)<br />
+> The _now_ variable will contain the time the function was called.
+
+* ***Creating a Queue***: Create a queue like this: ```Queue myQueue;```
+
+* int Queue::scheduleFunction(queuedFunction **pFunction**, const char ***pId**, unsigned long **pInitialRun**, unsigned long **pRecur**)
+> Add a function to the queue.<br/>
+> ***Return Values:***<br/>
+>> **0** if successful.<br/>
+>> **-1** if unsuccessful (queue is full).<br/>
+
+ * **pFunction**: Function to put in the queue.
+ * ***pId**: Up to 8 character unique identifier. (Unless you change the length).
+ * **pInitialRun**: Initial run time, in milliseconds.
+ * **pRecur**: Recurrence period, in milliseconds.
+
+* int Queue::scheduleRemoveFunction(const char ***pId**)
+> Remove a function with given unique ID from the queue.<br />
+> ***Return Values:***<br/>
+>> **0** if successful. <br/>
+>> **-1** if unsuccessful.
+
+ * ***pId**: Unique id 
+
+* int Queue::scheduleChangeFunction(const char ***pId**, unsigned long **pNewNext**, unsigned long **pNewRecur**)
+> Change function in the queue.<br/>
+> ***Return Values:***<br/>
+>> **0** if successful. <br/>
+>> **-1** if unsuccessful.
+
+ * ***pId**: Unique identifier.
+ * **pNewNext**: Next time to run the function.
+ * **pNewRecur**: New recurrence time.
+
+* int Queue::scheduleRun(unsigned long **pNow**)
+> Run all the queued items.  Run this in a loop to execute the queue.<br/>
+> ***Return Values:***<br/>
+>> **-1** if unsuccessful.
+>> **Number of queue items successfully ran** otherwise.
+
+ * **pNow**: the current time, in Milliseconds.
+
+ License
+ -------
+
+ Copyright (c) 2012 Brad Luyster
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.