From c2d929d5ed3cd0e55d20a854c7f9784b0a2c2f69 Mon Sep 17 00:00:00 2001 From: Philipp Claves <pclaves@web.de> Date: Tue, 11 Oct 2011 22:03:14 +0200 Subject: [PATCH] Power: Add UPS Code --- Power/Makefile | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ Power/main.c | 116 ++++++++++++++ 2 files changed, 519 insertions(+) create mode 100644 Power/Makefile create mode 100644 Power/main.c diff --git a/Power/Makefile b/Power/Makefile new file mode 100644 index 0000000..c06b484 --- /dev/null +++ b/Power/Makefile @@ -0,0 +1,403 @@ +# WinAVR Sample 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". +# + +# MCU name + +# MCU = atmega1284p +MCU = attiny25 + +#ATmega 128 wird von mir nicht unterstützt oder nur teilweise! +#MCU = atmega128 + +#Fuse settings for ATTiny25 +ifeq ($(MCU), attiny25) + FUSE_BITS = -u -U lfuse:w:0x62:m -U hfuse:w:0xCE:m -U efuse:w:0xFF:m + HEX_FILE_NAME = TINY25 +endif + + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = out/power_$(HEX_FILE_NAME) + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + +# If there is more than one source file, append them above, or modify and +# uncomment the following: + +SRC = main.c + +#SRC = main.c usart.c stack.c timer.c cmd.c base64.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 = ../avrcryptolib-nightly/avrcryptolib/gf256mul/gf256mul.S + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +#EXTRAINCDIRS = ../avrcryptolib-nightly/avrcryptolib ../avrcryptolib-nightly/avrcryptolib/aes + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing +CFLAGS = -g -O$(OPT) \ +-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +-Wall -Wstrict-prototypes \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional 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 + + + +# Optional 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 + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# 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 = stk500v2 +#AVRDUDE_PROGRAMMER = usbtiny +#AVRDUDE_PROGRAMMER = USBasp + +#AVRDUDE_PORT = usb # programmer connected to USB port +AVRDUDE_PORT = /dev/ttyUSB0 # programmer connected to serial device +#AVRDUDE_PORT = lpt1 # programmer connected to parallel port + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex $(FUSE_BITS) +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +#AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -b 115200 -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS = -B 10 -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# 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 += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -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_FLAGS += -v -v + + + + +# --------------------------------------------------------------------------- + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +# Programming support using avrdude. +AVRDUDE = avrdude + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + + +# 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) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# 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. +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 + + + + +# 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 + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# 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) $@ + avr-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) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/Power/main.c b/Power/main.c new file mode 100644 index 0000000..5c2b56b --- /dev/null +++ b/Power/main.c @@ -0,0 +1,116 @@ +#define F_CPU 1000000 + +#include <avr/io.h> +#include <avr/wdt.h> +#include <util/delay.h> +#include <avr/sleep.h> +#include <avr/interrupt.h> +#define ADC_VBAT 2 + +#define PIN_RELAIS_OFF (1 << 0) +#define PIN_AC_ON (1 << 1) +#define PIN_STATUS (1 << 2) +#define PIN_RELAIS_ON (1 << 3) +#define PIN_VBAT (1 << 4) + +#define AC_ON() (PINB & PIN_AC_ON) + +uint8_t battery_on = 0; +#define BATTERY_RELAIS_ON() {PORTB |= PIN_RELAIS_ON; _delay_ms(5); PORTB &= ~PIN_RELAIS_ON; _delay_ms(5);} +#define BATTERY_RELAIS_OFF() {PORTB |= PIN_RELAIS_OFF; _delay_ms(5); PORTB &= ~PIN_RELAIS_OFF; _delay_ms(5);} + +#define BATTERY_TIMEOUT 20 +uint8_t battery_timeout = BATTERY_TIMEOUT; +#define BATTERY_VOLTAGE_THRESHOLD 1100 +#define BATTERY_VOLTAGE_MAX 1380 + +ISR(ADC_vect){ + ; +} + +void sleep(void){ + wdt_reset(); + set_sleep_mode(SLEEP_MODE_ADC); + sleep_mode(); +} + +uint16_t ADC_read(uint8_t channel) { + uint16_t result; + + ADMUX = channel | (1 << REFS1) | (1 << REFS2); // Select channel, 2.56V internal Reference voltage. + + ADCSRA = (1 << ADEN) | (1 << ADPS2) |(1 << ADIE); // | (1 << ADPS1) ; //Enable and set Prescaler /16 + + //Warmup read + ADCSRA |= (1 << ADSC); + sleep(); + while (ADCSRA & (1 << ADSC)) {;} + result = ADCW; + result = 0; + + //Actual Read + for(uint8_t i=0; i < 4; i++){ + ADCSRA |= (1 << ADSC); + sleep(); + while (ADCSRA & (1 << ADSC)) {;} + result += ADCW; + } + + //Disable ADC + ADCSRA &= ~(1 << ADEN); + + result /= 4; + + return result; +} + + +uint16_t ADC_read_voltage(uint8_t channel, uint16_t mvmax){ + uint32_t raw = ADC_read(channel); + return ((raw * (uint32_t)mvmax) / 1024L); +} + + +int main(void){ + wdt_enable(WDTO_500MS); + wdt_reset(); + sei(); + + DDRB = PIN_RELAIS_OFF | PIN_RELAIS_ON; + PRR = (1 << PRUSI) | (1 << PRTIM1) | (1 << PRTIM0); //Shutdown not needed hardware (USI and TIMER1) + + while (1){ + wdt_reset(); + if (AC_ON()){ + if (! battery_on) { + BATTERY_RELAIS_ON(); + battery_on = 1; + } + + DDRB |= PIN_STATUS; + PORTB |= PIN_STATUS; + + battery_timeout = BATTERY_TIMEOUT; + } else { + PORTB &= ~PIN_STATUS; + DDRB &= ~PIN_STATUS; + + + if (ADC_read_voltage(ADC_VBAT, BATTERY_VOLTAGE_MAX) <= BATTERY_VOLTAGE_THRESHOLD){ + battery_timeout--; +// //Battery voltage too low for too long. +// //Commit suicide + if ((battery_timeout == 0) && ((PINB & PIN_STATUS) == 0)){ + BATTERY_RELAIS_OFF(); +// //We should be dead by now, but clean the state +// //in case the capaciator lasts a little longer. + battery_on = 0; + battery_timeout = BATTERY_TIMEOUT; + } + } else { + battery_timeout = BATTERY_TIMEOUT; + } + } +// _delay_ms(10); + } +} \ No newline at end of file -- GitLab