1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 16:25:16 +03:00

Sources for Coprocessor Application

This commit is contained in:
romolo.manfredini@gmail.com 2012-10-03 16:03:25 +00:00
parent 3179dd1d41
commit b4a9d62b22
5 changed files with 2164 additions and 0 deletions

206
TinyApp/Common_Define.h Normal file
View file

@ -0,0 +1,206 @@
/*****************************************************************************/
#define TWI_CMD_PAGEUPDATE 0x01 // TWI Command to program a flash page
#define TWI_CMD_EXECUTEAPP 0x02 // TWI Command to jump to the application program
#define TWI_CMD_SETREAD_ADDRESS 0x03 // TWI Command to set address to read from
#define TWI_CMD_WRITE_DATA 0x04 // TWI Command send data to the application
#define TWI_CMD_REBOOT 0x55 // TWI Command to restart back in the bootloader
#define TWI_SUBCMD_SETDATETIME 0x74 // TWI Command to set the date and time
//#define TWI_CMD_BVERSION 0x04 // TWI Command to get the bootloader revision identifier
//#define TWI_CMD_ERASEFLASH 0x05 // TWI Command to erase the entire application section of flash memory
//#define TWI_CMD_GETERRCONDN 0x07 // TWI Command to get Error condition
/*****************************************************************************/
//#define BOOT_SETTLE_DELAY 100 // Debounce delay for the boot pin in MCU cycles
//#define SLAVE_ADDRESS 0xb0 // The address identifier of this slave device on the TWI (I2C) bus
#define INTVECT_PAGE_ADDRESS 0x000 // The location of the start of the interrupt vector table address
// Select the communcation interfacing type: TWI or USI
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
defined(__ATTINY45__) | defined(__ATTINY45V__) | \
defined(__ATTINY85__) | defined(__ATTINY85V__) | \
defined(__ATTINY24__) | defined(__ATTINY24A__) | \
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
defined(__ATTINY84__) | defined(__ATTINY84A__) | \
defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
defined(__ATTINY4313__) | defined(__ATTINY4313A__) | \
defined(__ATTINY261__) | defined(__ATTINY261A__) | \
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
defined(__ATTINY861__) | defined(__ATTINY861A__) | \
defined(__ATTINY43U__) | \
defined(__ATTINY87__) | \
defined(__ATTINY167__)
#define __USI__ // set the communication type as USI
#endif */
#define __USI__ // set the communication type as USI
/*#if defined(__ATTINY48__) | defined(__ATTINY88__) | \
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__) | \
defined(__ATMEGA48__)
#define __TWI__
#endif */
/***************************************************************/
// Page size selection for the controller with 2K flash
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
defined(__ATTINY24__) | defined(__ATTINY24A__) | \
defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
defined(__ATTINY261__) | defined(__ATTINY261A__)
// The flash memory page size for these devices
#define PAGE_SIZE 32
// Page 32, the start of bootloader section
#define BOOT_PAGE_ADDRESS 0X0400
// 2KB of flash divided by pages of size 32 bytes
#define TOTAL_NO_OF_PAGES 64
// The number of pages being used for bootloader code
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
#endif */
// Page size selection for the controller with 4K flash
/*#if defined(__ATTINY45__) | defined(__ATTINY45V__) | \
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
defined(__ATTINY4313__) | defined(__ATTINY4313A__) | \
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
defined(__ATTINY43U__) | \
defined(__ATTINY48__) | \
defined(__ATMEGA48__) | \
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__)
// The flash memory page size for these devices
#define PAGE_SIZE 64
// Page 48, the start of bootloader section
#define BOOT_PAGE_ADDRESS 0X0C00
// 4KB of flash divided by pages of size 64 bytes
#define TOTAL_NO_OF_PAGES 64
// The number of pages being used for bootloader code
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
#endif */
// Page size selection for the controller with 8K flash
/*#if defined(__ATTINY85__) | defined(__ATTINY85V__) | \
defined(__ATTINY84__) | defined(__ATTINY84A__) | \
defined(__ATTINY861__) | defined(__ATTINY861A__) | \
defined(__ATTINY87__) | \
defined(__ATTINY88__)
// The flash memory page size for these devices
#define PAGE_SIZE 64
// Page 112, the start of bootloader section
#define BOOT_PAGE_ADDRESS 0X1C00
// 8KB of flash divided by pages of size 64 bytes
#define TOTAL_NO_OF_PAGES 128
// The number of pages being used for bootloader code
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
// // For bounds check during page write/erase operation to protect the bootloader code from being corrupted
// #define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
//#endif*/
// Page size selection for the controller with 16K flash
//#if defined(__ATTINY167__)
// The flash memory page size for Atiny167
#define PAGE_SIZE 128
// Page 120, the start of bootloader section
#define BOOT_PAGE_ADDRESS 0X3800
// 16KB of flash divided by pages of size 128 bytes
#define TOTAL_NO_OF_PAGES 128
// The number of pages being used for bootloader code
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
//#endif
/*****************************************************************************/
/*****************************************************************************/
// Select the correct Bit name of to SELFPROGRAMming
/*#if defined(__ATTINY48__) | defined(__ATTINY48A__) | \
defined(__ATTINY88__) | defined(__ATTINY88A__) | \
defined(__ATMEGA48__) | \
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__)
#define SELFPROGEN SELFPRGEN
#endif */
/*****************************************************************************/
/*****************************************************************************/
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
defined(__ATTINY45__) | defined(__ATTINY45V__) | \
defined(__ATTINY85__) | defined(__ATTINY85V__) | \
defined(__ATTINY87__) | defined(__ATTINY167__) */
#define SELFPROGEN SPMEN
//#endif
/*****************************************************************************/
/*****************************************************************************/
#define WDT_TIMEOUT_8s ( _BV( WDP3 ) | _BV( WDP0 ) ) // Watchdog timeout for inactivity in the boot section
#define WDT_TIMEOUT_16ms 0 // Watchdog timeout for system reset (cleanup) before jump to application
#define WDT_TIMEOUT_min WDT_TIMEOUT_16ms // The minimum watchdog reset time interval for jump to application
/*****************************************************************************/
/*****************************************************************************/
#define STATUSMASK_SPMBUSY 0x01 // The mask bit for SPM busy status code
#define STATUSMASK_BLSCERR 0x02 // The mask bit for attempt to override bootloader section
#define STATUSMASK_TWIABORT 0x04 // The mask bit for indicating TWI abort fn called
#define STATUSMASK_SLTR_BUSY 0x08 // The mask bit for slave transmit
#define STATUSMASK_SLRBAA_BUSY 0x10 // The mask bit for slave receive and ack
#define STATUSMASK_SLRBAN_BUSY 0x20 // The mask bit for slave receive and Nack
#define STATUSMASK_EEPROM_BUSY 0x40 // The mask bit for EEPROM busy
#define STATUSMASK_BOOTLOADER 0x80 // The mask bit for bootloader operations
/*****************************************************************************/
/*****************************************************************************/
#define EEMEM_ADDR_AVERSION 0x05 // The address in EEPROM where application revision identifier will be stored
#define BVERSION 0x96 // This bootloader revision identifier
//static void UpdatePage (uint16_t);
#ifndef _BV
#define _BV( __BIT_POSITION__ ) ( 1 << __BIT_POSITION__ )
#endif
//#ifdef _BV
//#warning _BV now stands defined
//#endif

624
TinyApp/Makefile Normal file
View file

@ -0,0 +1,624 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile
#
# 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 = attiny167
# 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.
# Typical values are:
# F_CPU = 1000000
# F_CPU = 1843200
# F_CPU = 2000000
# F_CPU = 3686400
# F_CPU = 4000000
# F_CPU = 7372800
# F_CPU = 8000000
# F_CPU = 11059200
# F_CPU = 14745600
# F_CPU = 16000000
# F_CPU = 18432000
# F_CPU = 20000000
F_CPU = 8000000
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = TinyApp
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
# 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 = stabs
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 = c:\progs\iccv7avr\include
# 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 for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS
#---------------- Compiler Options C ----------------
# -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)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wno-main
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
# Next line dumps rtl file
#CFLAGS += -dr
#CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
#---------------- Compiler Options C++ ----------------
# -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
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
#CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: 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]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
#---------------- 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
# List any extra directories to look for libraries 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.
EXTRALIBDIRS =
#---------------- 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,--section-start,.data=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 += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
LDFLAGS += -Wl,--section-start=.text=0x00D0
LDFLAGS += -Wl,--section-start=.vectors=0x0080
LDFLAGS += -T avr3-167.ld
LDFLAGS += -N
#---------------- 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 = stk500
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com3
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)
#---------------- 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
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
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 C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -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_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym bin
#build: lib
elf: $(TARGET).elf
hex: $(TARGET).hex
bin: $(TARGET).bin
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
# 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) --mcu=$(MCU) --format=avr $(TARGET).elf
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
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
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --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 $< $@
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
# 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 $< > $@
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)
# 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.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.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).bin
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
# 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

929
TinyApp/TinyApp.c Normal file
View file

@ -0,0 +1,929 @@
//#include <ioavr.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/boot.h>
#include "stdint.h"
//#include <inavr.h>
#include "Common_Define.h"
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "USI_TWI_Slave.h"
#define sbi(port,bit) (port |= (1<<bit)) //set bit in port
#define cbi(port,bit) (port &= ~(1<<bit)) //clear bit in port
#define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
#define FORCE_INDIRECT(ptr) __asm__ __volatile__ ("" : "=e" (ptr) : "0" (ptr))
#define NOINLINE __attribute__ ((noinline))
// Version number, sent in first byte of response
#define VERSION 0x03
/*****************************************************************************/
// USI_TWI write states.
#define USI_TWI_WRITE_ADDR_HI_BYTE (0x00)
#define USI_TWI_WRITE_ADDR_LO_BYTE (0x01)
#define USI_TWI_WRITE_DATA_BYTE (0x02)
// USI_TWI overflow states.
#define USI_TWI_OVERFLOW_STATE_NONE (0x00)
#define USI_TWI_OVERFLOW_STATE_ACK_PR_RX (0x01)
#define USI_TWI_OVERFLOW_STATE_DATA_RX (0x02)
#define USI_TWI_OVERFLOW_STATE_ACK_PR_TX (0x03)
#define USI_TWI_OVERFLOW_STATE_PR_ACK_TX (0x04)
#define USI_TWI_OVERFLOW_STATE_DATA_TX (0x05)
#define DATA_SIZE 16 // Receive data buffer size
#define TEMPERATURE 0b01001011
// Signature row addresses
#define TSOFFSET 5
#define TSGAIN 7
// Bits in AdcControl
#define ADC_RUNNING 0x80
#define ADC_COUNT_MASK 0x0F
uint8_t AdcControl ;
uint16_t AdcTotal ;
int8_t T_offset ;
uint8_t T_gain ;
int16_t T_mult ;
// USI_TWI state values.
static uint8_t USI_TWI_SLAVE_Write_State;
static uint8_t USI_TWI_SLAVE_Overflow_State;
static uint8_t Command_Flag;
// TWI flag values.
// static uint8_t USI_TWI_SLAVE_Address_Update;
// Slave Each page address values.
//static uint16_t USI_TWI_SLAVE_PAGE_Address;
uint8_t DataBuffer[DATA_SIZE];
static uint8_t *bufferPtr ;
static uint8_t Value;
uint8_t Tx_buffer[22] ;
int8_t Temperature;
static uint8_t Tx_index ;
typedef struct
{
unsigned char second; //enter the current time, date, month, and year
unsigned char minute;
unsigned char hour;
unsigned char date;
unsigned char month;
unsigned int year;
} t_time ;
t_time Time ;
uint8_t ActivityFlag ;
void main (void) __attribute__((noreturn)) ;
char not_leap(void) ; //check for leap year
void updateTime(uint8_t amount) ;
void set_clock( uint8_t speed ) ;
void checkPowerSave( void ) ;
static void Disable_WatchDogTimer(void) ;
static void Init_WatchDogTimer(void) ;
void enableAdc( void ) ;
void disableAdc( void ) ;
char not_leap(void) //check for leap year
{
t_time *p = &Time ;
FORCE_INDIRECT(p) ;
if (!(p->year%100))
return (char)(p->year%400);
else
return (char)(p->year%4);
}
void updateTime(uint8_t amount)
{
t_time *p = &Time ;
FORCE_INDIRECT(p) ;
if (++p->second >= 60) //keep track of time, date, month, and year
{
p->second -= 60 ;
if (++p->minute >= 60)
{
p->minute=0;
if (++p->hour >= 24)
{
p->hour=0;
if (++p->date >= 32)
{
p->month++;
p->date=1;
}
else if (p->date == 31)
{
if ((p->month==4) || (p->month==6) || (p->month==9) || (p->month==11))
{
p->month++;
p->date=1;
}
}
else if (p->date==30)
{
if(p->month==2)
{
p->month++;
p->date=1;
}
}
else if (p->date==29)
{
if((p->month==2) && (not_leap()))
{
p->month++;
p->date=1;
}
}
if (p->month >= 13)
{
p->month=1;
p->year++;
}
}
}
}
}
ISR(TIMER0_OVF_vect)
{
TCCR0B = 5 ; // Divide/128
while((ASSR & 0b00011011) != 0x00);/*Wait until TCNT0, OCR0A, TCCR0A and TCCR0B updated*/
updateTime(1) ;
}
void checkPowerSave()
{
if ( PINB & 0x05 )
{
ActivityFlag = 0 ;
return ; // I2C line(s) are high, power is ON
}
if ( ActivityFlag < 3 )
{
return ;
}
// The AVR toolchain includes a header file, sleep.h, which has functions for setting
//sleep mode, disabling BOD, and putting the device into sleep. These functions are
//called:
//.. set_sleep_mode() selects which sleep mode to use when the sleep
//instruction is executed
//.. sleep_enable() enables sleep modes
//.. sleep_bod_disable() disables BOD while sleeping
//.. sleep_cpu() executes the sleep instruction
CLKPR = 0x80 ; // Do inline for quick response
CLKPR = 0 ; // Full speed 8.0MHz
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
TIMSK0 |= (1 << TOIE0) ;
disableAdc() ;
PRR = 0x3B ; // Power off USI
Disable_WatchDogTimer() ;
set_clock( 2 ) ; // Slow to 2.0 MHz
while ( ( PINB & 0x05 ) == 0 ) // I2C lines are low
{
sleep_enable();
sleep_bod_disable();
sei();
sleep_cpu();
sleep_disable();
cli() ;
wdt_reset() ;
}
PRR = 0x39 ; // USI re-powered
Init_WatchDogTimer() ;
USI_TWI_SLAVE_Init();
enableAdc() ;
TIMSK0 &= ~(1 << TOIE0) ;
USISR = (1<<USISIF) | (1<<USIOIF) | (1<<USIPF) ; // Clear interrupt flags.
set_clock( 5 ) ; // Slow to 0.25MHz
ActivityFlag = 0 ;
}
/******************************************************************************/
/* Local variables */
//static uint8_t TWI_RxBuf[TWI_RX_BUFFER_SIZE];
//static volatile uint8_t TWI_RxHead;
//static volatile uint8_t TWI_RxTail;
//static uint8_t TWI_TxBuf[TWI_TX_BUFFER_SIZE];
//static volatile uint8_t TWI_TxHead;
//static volatile uint8_t TWI_TxTail;
#define USI_TWI_SlaveAddress 0x35
//********** USI_TWI functions **********//
static void USI_TWI_SLAVE_Init()
{
// USI_TWI_SlaveAddress = TWI_OwnAddress;
DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input
PORT_USI &= ~(1<<PORT_USI_SDA); // Set SDA high
DDR_USI |= (1<<PORT_USI_SCL); // Set SCL as output
PORT_USI |= (1<<PORT_USI_SCL); // Set SCL high
USICR = /*(0<<USISIE)|(0<<USIOIE)|*/ // Disable Start Condition Interrupt. Disable Overflow Interrupt.
(1<<USIWM1)|(1<<USIWM0)| // Set USI in Two-wire mode. No USI Counter overflow prior
// to first Start Condition (potentail failure)
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge
(0<<USITC);
// Clear the interrupt flags and reset the counter.
USISR = (1<<USISIF) | (1<<USIOIF) | (1<<USIPF) | // Clear interrupt flags.
(1<<USIDC) |(0x0<<USICNT0); // USI to sample 8 bits or 16 edge toggles.
// USI TWI Start condition interrupt enable.
// USICR |= (1<<USISIE); // Not needed, all are polled
}
// the below function is added by
/*****************************************************************************/
static void USI_TWI_SLAVE_Abort()
{
USICR = /*(0<<USISIE)|(0<<USIOIE)|*/ // Disable Start Condition Interrupt. Disable Overflow Interrupt.
(0<<USIWM1)|(0<<USIWM0)| // reset USI in Two-wire mode. No USI Counter overflow prior
// to first Start Condition (potentail failure)
(0<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = internal, positive edge
(0<<USITC);
// Reset SCL and SDA lines of TWI Communication interface
DDR_USI &= ~(1<<PORT_USI_SDA);
PORT_USI &= ~(1<<PORT_USI_SDA); // Set SDA low
// PORTA &= ~8 ;
DDR_USI |= ~(1<<PORT_USI_SCL);
PORT_USI |= ~(1<<PORT_USI_SCL); // Set SCL low
// Clear the USI DATA register.
USIDR = 0x00;
// Clear the interrupt flags and reset the counter.
USISR = (1<<USISIF) | (1<<USIOIF) | (1<<USIPF) | // Clear interrupt flags.
(1<<USIDC) |(0x0<<USICNT0); // USI to sample 8 bits or 16 edge toggles.
}
static void USI_TWI_SLAVE_ReadAndProcessPacket ()
{
set_clock( 5 ) ; // Slow to 0.25MHz
while(1)
{
// Check for USI TWI start condition.
if (USISR & (1<<USISIF))
{
CLKPR = 0x80 ; // Do inline for quick response
CLKPR = 0 ; // Full speed 8.0MHz
// Process the USI TWI start condition.
USI_TWI_SLAVE_Process_Start_Condition();
}
// Check for USI_TWI_SLAVE overflow condition.
if (USISR & (1<<USIOIF))
{
ActivityFlag = 0 ;
// Handle the TWI overflow condition.
USI_TWI_SLAVE_Process_Overflow_Condition();
/* as this part is already taken care...
// Should we update the twi address?
if (USI_TWI_SLAVE_Address_Update)
{
// Mark the bootloader as active.
bootloader_active = 1;
// Check for the special address to exit the bootloader.
if (USI_TWI_SLAVE_PAGE_Address != 0xffff)
{
// Set the twi address. This will load the corresponding page from
// flash into the programming buffer for reading and writing.
// prog_buffer_set_address(USI_TWI_SLAVE_PAGE_Address);
}
// Reset the flag.
USI_TWI_SLAVE_Address_Update = 0;
}
.....Till here.........*/
}
// Check for TWI stop condition.
if (USISR & (1<<USIPF))
{
// Clear the stop condition flag.
USISR = (1<<USIPF);
// Check for the special address to exit the bootloader.
if ( Run_boot )
{
// Set the flag to have the bootloader eixt.
break ;
}
else
{
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_NONE ;
Command_Flag = 0 ;
}
set_clock( 5 ) ; // Slow to 0.25MHz
}
wdt_reset() ;
if ( TIFR0 & 1 )
{
CLKPR = 0x80 ; // Do inline for quick response
CLKPR = 0 ; // Full speed 8.0MHz
TIFR0 = 1 ; // CLEAR flag (write 1)
updateTime(1) ;
t_time *p = &Time ;
uint8_t *q = &Tx_buffer[1] ;
// FORCE_INDIRECT(p) ;
*q++ = p->second ;
*q++ = p->minute ;
*q++ = p->hour ;
*q++ = p->date ;
*q++ = p->month ;
*q++ = p->year ;
*q++ = p->year >> 8 ;
*q++ = Temperature ;
*q++ = T_offset ;
*q++ = T_gain ;
// *q++ = MCUSR ;
if ( ActivityFlag < 255 )
{
ActivityFlag += 1 ;
}
set_clock( 5 ) ; // Slow to 0.25MHz
}
checkPowerSave() ;
if ( ( AdcControl & ADC_RUNNING ) == 0 )
{
ADMUX = TEMPERATURE ; // Internal 1.1V REF and ADCx
ADCSRA |= (1<<ADSC); // do single conversion
AdcControl |= ADC_RUNNING ;
}
else
{
if ( ( ADCSRA & (1<<ADSC) ) == 0 )
{
AdcControl &= ~ADC_RUNNING ;
AdcControl += 1 ;
if ( ( AdcControl & ADC_COUNT_MASK ) > 1 )
{ // Skip first conversion
AdcTotal += ADCW ;
}
if ( ( AdcControl & ADC_COUNT_MASK ) >= 9 )
{
AdcTotal += 4 ;
AdcTotal >>= 3 ;
{
int16_t temp ;
temp = AdcTotal ;
temp -= 298 ;
temp += T_offset ;
temp *= T_mult ;
temp >>= 8 ;
temp += 25 ;
Temperature = temp ;
}
AdcControl = 0 ;
AdcTotal = 0 ;
// if (AdcTotal < 0x00f6)
// {
// Temperature=-40;
// }
// else if (AdcTotal < 0x0144)
// {
// Temperature=((AdcTotal*78)/65)-40;
// }
// else
// {
// Temperature=((((AdcTotal-324)*600)/74)+250)/10;
// }
}
}
}
} // while
// Disable_WatchDogTimer(); // After Reset the WDT state does not change
// void (*FuncPtr) (void) = (void (*)(void)) (0x0080); // Set up function pointer to address 0x0080
// FuncPtr ();
TCCR0B = 0 ;
USICR = 0 ;
USISR = 0 ;
PRR = 0 ;
CLKPR = 0x80 ; // Do inline for quick response
CLKPR = 0 ; // Full speed 8.0MHz
((void (*)(void)) (0))() ;
}
/******************************************************************************/
//Description:
// Process the USI TWI start condition. This is called when the TWI master initiates
// communication with a USI TWI slave by asserting the TWI start condition.
/******************************************************************************/
static void USI_TWI_SLAVE_Process_Start_Condition(void)
{
// Wait until the "Start Condition" is complete when SCL goes low. If we fail to wait
// for SCL to go low we may miscount the number of clocks pulses for the data because
// the transition of SCL could be mistaken as one of the data clock pulses.
while ((PIN_USI & (1<<PORT_USI_SCL)));
// Reset the overflow state.
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_NONE;
// Clear the interrupt flags and reset the counter.
USISR = (1<<USISIF) | (1<<USIOIF) | (1<<USIPF) | // Clear interrupt flags.
(0x00<<USICNT0); // USI to sample 8 bits or 16 edge toggles.
// Update the interrupt enable, wire mode and clock settings.
USICR = /*(1<<USISIE) | (1<<USIOIE) |*/ // Enable Overflow and Start Condition Interrupt.
(1<<USIWM1) | (1<<USIWM0) | // Maintain USI in two-wire mode with clock stretching.
(1<<USICS1) | (0<<USICS0) | (0<<USICLK) | // Shift Register Clock Source = External, positive edge
(0<<USITC); // No toggle of clock pin.
}
/******************************************************************************/
/*******************************************************************************
Description:
Processes the USI_TWI_SLAVE overflow condition.
This is called when the USI TWI 4-bit counterboverflows indicating the
TWI master has clocked in/out a databyte or a singleback/nack byte following a
databyte transfer.
*******************************************************************************/
void USI_TWI_SLAVE_Process_Overflow_Condition(void)
{
// Buffer the USI data.
uint8_t Usi_Data = USIDR;
// Handle the interrupt based on the overflow state.
switch (USI_TWI_SLAVE_Overflow_State)
{
/***********************************************************************/
// Handle the first byte transmitted from master -- the slave address.
case USI_TWI_SLAVE_OVERFLOW_STATE_NONE:
// Are we receiving our address?
if ((Usi_Data >> 1) == USI_TWI_SlaveAddress)
{
// Yes. Are we to send or receive data?
if((Usi_Data & 0x01) == 0x01)
{
//USI TWI Slave has to transmit the data byte
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_TX;
Tx_buffer[0] = VERSION ; // Version number
Tx_index = 0 ;
}
else
{
//USI TWI Slave has to Receive the data byte
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX;
}
// Reset the write state.
//.. added the below statement at Command_flag=1
//USI_TWI_SLAVE_Write_State = USI_TWI_SLAVE_WRITE_ADDR_HI_BYTE;
// Set SDA for output.
PORT_USI |= (1<<PORT_USI_SDA);
DDR_USI |= (1<<PORT_USI_SDA);
// Load data for ACK.
USIDR = 0;
// Reload counter for ACK -- two clock transitions.
USISR = 0x0E;
}
else
{
// No. Reset USI to detect start condition. Update the interrupt enable,
// wire mode and clock settings. Note: At this time the wire mode must
// not be set to hold the SCL line low when the counter overflows.
// Otherwise, this TWI slave will interfere with other TWI slaves.
USICR = /*(1<<USISIE) | (0<<USIOIE) |*/ // Enable Start Condition Interrupt. Disable overflow.
(1<<USIWM1) | (0<<USIWM0) | // Maintain USI in two-wire mode without clock stretching.
(1<<USICS1) | (0<<USICS0) | (0<<USICLK) | // Shift Register Clock Source = External, positive edge
(0<<USITC); // No toggle of clock pin.
}
break;
/***********************************************************************/
// Ack sent to master so prepare to receive more data.
case USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX:
if(Command_Flag == 0)
{
// Update our state.
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_CMD_RX;
}
else if(Command_Flag == 1)
{
// Update our state.
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_DATA_RX;
}
// else if(Command_Flag == 2)
// {
// // Update our state.
// USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_AVERSION;
// }
// else if(Command_Flag == 3)
// {
// // Update our state.
// USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_BVERSION;
// }
// else if(Command_Flag == 4)
// {
// // Update our state.
// USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_GETERRCONDN;
// }
// Set SDA for input
DDR_USI &= ~(1<<PORT_USI_SDA);
PORT_USI &= ~(1<<PORT_USI_SDA);
break;
/**************************************************************************/
case USI_TWI_SLAVE_OVERFLOW_STATE_CMD_RX:
// Update our state
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_NONE;
// Check the command received type.
if(Usi_Data == TWI_CMD_REBOOT)
{
// reset the controller ...
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX ;
// set this flag to receive data
Command_Flag = 0 ;
Run_boot = 1 ;
}
else if(Usi_Data == TWI_CMD_WRITE_DATA)
{
// set this flag to receive data
Command_Flag =1;
// ReceiveType = TWI_CMD_SETDATETIME ;
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX ;
USI_TWI_SLAVE_Write_State = USI_TWI_SLAVE_WRITE_DATA_BYTE;
bufferPtr = DataBuffer ;
Value = 0 ;
}
// else if(Usi_Data == TWI_CMD_BVERSION)
// {
// // set this flag to receive data
// Command_Flag =3;
// }
// else if(Usi_Data == TWI_CMD_ERASEFLASH)
// {
// // erase the flash here itself .......
// // set this flag to receive data
// Command_Flag =0;
// }
// else if(Usi_Data == TWI_CMD_GETERRCONDN)
// {
// // set this flag to receive data
// Command_Flag =4;
// }
else
{
// set this flag to receive data
Command_Flag =0;
USI_TWI_SLAVE_Abort();
}
// Set SDA for output.
PORT_USI |= (1<<PORT_USI_SDA);
DDR_USI |= (1<<PORT_USI_SDA);
// Load data for ACK.
USIDR = 0;
// Reload counter for ACK -- two clock transitions.
USISR = 0x0E;
break;
// Data received from master so prepare to send ACK.
case USI_TWI_SLAVE_OVERFLOW_STATE_DATA_RX:
// Update our state.
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX;
// Always make sure the Command_Flag is 1
Command_Flag = 1;
// Check the TWI write state to determine what type of byte we received.
// if (USI_TWI_SLAVE_Write_State == USI_TWI_SLAVE_WRITE_ADDR_HI_BYTE)
// {
// // Set the twi address high byte.
// USI_TWI_SLAVE_PAGE_Address = Usi_Data;
// // Set the next state.
// USI_TWI_SLAVE_Write_State = USI_TWI_SLAVE_WRITE_ADDR_LO_BYTE;
// }
// else if (USI_TWI_SLAVE_Write_State == USI_TWI_SLAVE_WRITE_ADDR_LO_BYTE)
// {
// // Set the address low byte.
// USI_TWI_SLAVE_PAGE_Address = (USI_TWI_SLAVE_PAGE_Address << 8) | Usi_Data;
// // Set the programming address.
//// USI_TWI_SLAVE_Address_Update = 1;
// Value = 0;
// bufferPtr = pageBuffer ;
// // Set the next state.
// USI_TWI_SLAVE_Write_State = USI_TWI_SLAVE_WRITE_DATA_BYTE;
// }
// else
{
// Write the data to the buffer.
//USI_TWI_SLAVE_prog_buffer_set_byte(Usi_Data);
*bufferPtr = Usi_Data;
// Increment the byte address within the page.
//++prog_byte_address;
++bufferPtr;
++Value;
// Check the byte address for wrapping. // check later
if ( DataBuffer[0] == TWI_SUBCMD_SETDATETIME )
{
if (Value >= 8 ) // Size of time structure+1
{
if ( Value == 8 )
{
// Set the date and time
t_time *p = &Time ;
FORCE_INDIRECT(p) ;
p->second = DataBuffer[1] ;
p->minute = DataBuffer[2] ;
p->hour = DataBuffer[3] ;
p->date= DataBuffer[4] ;
p->month = DataBuffer[5] ;
p->year = DataBuffer[6] + ( DataBuffer[7] << 8 ) ;
}
Value = 9 ;
bufferPtr = &DataBuffer[DATA_SIZE-1] ;
}
}
if ( Value > DATA_SIZE )
{
Value = DATA_SIZE ;
bufferPtr = &DataBuffer[DATA_SIZE-1] ; // Overwrite last byte
}
}
// Set SDA for output.
PORT_USI |= (1<<PORT_USI_SDA);
DDR_USI |= (1<<PORT_USI_SDA);
// PORTA |= 8 ;
// Load data for ACK.
USIDR = 0;
// Reload counter for ACK -- two clock transitions.
USISR = 0x0E;
break;
/***********************************************************************/
case USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_AVERSION:
// Update our state.
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_PR_ACK_TX;
// Set SDA for input.
DDR_USI &= ~(1<<PORT_USI_SDA);
// PORTA &= ~8 ;
PORT_USI &= ~(1<<PORT_USI_SDA);
// Reload counter for ACK -- two clock transitions.
USISR = 0x0E;
break;
/***********************************************************************/
case USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_BVERSION:
break;
/***********************************************************************/
case USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_GETERRCONDN:
break;
/***********************************************************************/
// ACK received from master. Reset USI state if NACK received.
case USI_TWI_SLAVE_OVERFLOW_STATE_PR_ACK_TX:
// Check the lowest bit for NACK? If set, the master does not want more data.
if (Usi_Data & 0x01)
{
// Update our state.
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_NONE;
// Reset USI to detect start condition. Update the interrupt enable,
// wire mode and clock settings. Note: At this time the wire mode must
// not be set to hold the SCL line low when the counter overflows.
// Otherwise, this TWI slave will interfere with other TWI slaves.
USICR = /*(1<<USISIE) | (0<<USIOIE) |*/ // Enable Start Condition Interrupt. Disable overflow.
(1<<USIWM1) | (0<<USIWM0) | // Maintain USI in two-wire mode without clock stretching.
(1<<USICS1) | (0<<USICS0) | (0<<USICLK) | // Shift Register Clock Source = External, positive edge
(0<<USITC); // No toggle of clock pin.
// Clear the overflow interrupt flag and release the hold on SCL.
USISR |= (1<<USIOIF);
return;
}
/***********************************************************************/
// Handle sending a byte of data.
case USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_TX:
// Update our state.
// USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX;
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_AVERSION;
// Set SDA for output.
PORT_USI |= (1<<PORT_USI_SDA);
DDR_USI |= (1<<PORT_USI_SDA);
// PORTA |= 8 ;
// Get the data to send.
// USIDR = prog_buffer_get_byte();
USIDR = Tx_buffer[Tx_index++] ; // Send this for testing
break;
/***********************************************************************/
// Data sent to to master so prepare to receive ack.
case USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX:
// Update our state.
USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_PR_ACK_TX;
// Set SDA for input.
DDR_USI &= ~(1<<PORT_USI_SDA);
// PORTA &= ~8 ;
PORT_USI &= ~(1<<PORT_USI_SDA);
// Reload counter for ACK -- two clock transitions.
USISR = 0x0E;
break;
/***********************************************************************/
}
// Clear the overflow interrupt flag and release the hold on SCL.
USISR |= (1<<USIOIF);
}
uint8_t state = 0;
// __no_init uint8_t pageBuffer[PAGE_SIZE];
//uint16_t time_lapse_sec = 0;
#define gtimeout WDT_TIMEOUT_8s
// uint8_t volatile gtimeout;
//uint8_t statusCode = 0;
/***********************************************************************/
static void Disable_WatchDogTimer (void)
{
/*
Timed sequence
Interrupts are already disabled else additional code may go in to avoid
the servicing of interrupt in between the timed sequence
*/
wdt_reset();
WDTCR = (1 << WDCE) | ( 1 << WDE ) ;
MCUSR = 0 ;
WDTCR = 0 ;
}
/***********************************************************************/
static void Init_WatchDogTimer (void)
{
/*
Timed sequence to initialize watchdog timer
for the given mode set in gtimeout variable
Cross calls during maximum optimization can
cause more than 4 cycles delay between change
enable for WDT and setting values
*/
wdt_reset();
WDTCR = (1 << WDCE) | ( 1 << WDE ) ;
WDTCR = ( 1 << WDE ) | gtimeout ;
}
/***********************************************************************/
NOINLINE void set_clock( uint8_t speed )
{
volatile uint8_t *ptr ;
ptr = &CLKPR ;
*ptr = 0x80 ;
*ptr = speed ;
}
/***********************************************************************/
// Main Starts from here
void main (void)
{
USI_TWI_SLAVE_Init();
//__enable_interrupt();
Init_WatchDogTimer() ;
/*RTC 32.768kHz, div 128 */
{
PRR = 0x39 ;
TCCR0A = 0 ;
TCCR0B = 5 ; // Divide/128
ASSR = 0x20 ; // Async mode
while((ASSR & 0b00011011) != 0x00);/*Wait until TCNT0, OCR0A, TCCR0A and TCCR0B updated*/
TIFR0 = 0x01;/*Clear T0 int flag*/
}
t_time *p = &Time ;
FORCE_INDIRECT(p) ;
p->second = 5 ;
p->minute = 6 ;
p->hour = 16 ;
p->date= 23 ;
p->month = 9 ;
p->year = 2012 ;
bufferPtr = DataBuffer ;
T_offset = boot_signature_byte_get( TSOFFSET ) ;
T_gain = boot_signature_byte_get( TSGAIN ) ;
T_mult = 32768U / T_gain ;
enableAdc() ;
for(;;)
{
USI_TWI_SLAVE_ReadAndProcessPacket() ;
}
}
// Enable ADC
void enableAdc()
{
cbi( PRR, PRADC ) ; // Power the ADC
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // set ADC prescaler to , 8MHz / 64 = 125kHz
}
// Disable ADC
void disableAdc()
{
ADCSRA = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) ; // set ADC prescaler to , 8MHz / 256 = 30kHz
sbi( PRR, PRADC ) ; // Power Down the ADC
}

174
TinyApp/USI_TWI_Slave.h Normal file
View file

@ -0,0 +1,174 @@
#ifdef __USI__
/****************************************************************************/
static void USI_TWI_SLAVE_Init( void );
static void USI_TWI_SLAVE_Abort(void);
static void USI_TWI_SLAVE_ReadAndProcessPacket(void);
static void USI_TWI_SLAVE_Process_Start_Condition(void);
void USI_TWI_SLAVE_Process_Overflow_Condition(void);
// void prog_buffer_set_byte(uint8_t );
// uint8_t bootloader_exit;
uint8_t Run_boot ;
#define TRUE 1
#define FALSE 0
// TWI write states.
#define USI_TWI_SLAVE_WRITE_ADDR_HI_BYTE (0x00)
#define USI_TWI_SLAVE_WRITE_ADDR_LO_BYTE (0x01)
#define USI_TWI_SLAVE_WRITE_DATA_BYTE (0x02)
// TWI overflow states.
#define USI_TWI_SLAVE_OVERFLOW_STATE_NONE (0x00)
#define USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX (0x01)
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_RX (0x02)
#define USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_TX (0x03)
#define USI_TWI_SLAVE_OVERFLOW_STATE_PR_ACK_TX (0x04)
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX (0x05)
// newly added ..
#define USI_TWI_SLAVE_OVERFLOW_STATE_CMD_RX (0x06)
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_AVERSION (0x07)
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_BVERSION (0x08)
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_GETERRCONDN (0x09)
//////////////////////////////////////////////////////////////////////
// typedef unsigned char uint8_t;
//////////////////////////////////////////////////////////////////
///////////////// Driver Buffer Definitions //////////////////////
//////////////////////////////////////////////////////////////////
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
#define TWI_RX_BUFFER_SIZE (16)
#define TWI_RX_BUFFER_MASK ( TWI_RX_BUFFER_SIZE - 1 )
#if ( TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK )
#error TWI RX buffer size is not a power of 2
#endif
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
#define TWI_TX_BUFFER_SIZE (16)
#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )
#if ( TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK )
#error TWI TX buffer size is not a power of 2
#endif
#define USI_SLAVE_CHECK_ADDRESS (0x00)
#define USI_SLAVE_SEND_DATA (0x01)
#define USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA (0x02)
#define USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA (0x03)
#define USI_SLAVE_REQUEST_DATA (0x04)
#define USI_SLAVE_GET_DATA_AND_SEND_ACK (0x05)
//////////////////////////////////////////////////////////////////////////
/*#if defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
defined(__ATTINY4313__) | defined(__ATTINY4313A__) */
// #define DDR_USI DDRB
// #define PORT_USI PORTB
// #define PIN_USI PINB
// #define PORT_USI_SDA PORTB5
// #define PORT_USI_SCL PORTB7
// #define PIN_USI_SDA PINB5
// #define PIN_USI_SCL PINB7
// #define USI_START_COND_INT USISIF
// #define USI_START_VECTOR USI_STRT_vect
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
//#endif
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
// defined(__ATTINY45__) | defined(__ATTINY45V__) | \
// defined(__ATTINY85__) | defined(__ATTINY85V__) */
// #define DDR_USI DDRB
// #define PORT_USI PORTB
// #define PIN_USI PINB
// #define PORT_USI_SDA PORTB0
// #define PORT_USI_SCL PORTB2
// #define PIN_USI_SDA PINB0
// #define PIN_USI_SCL PINB2
// #define USI_START_COND_INT USICIF
// #define USI_START_VECTOR USI_START_vect
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
//#endif
/*#if defined(__ATTINY24__) | defined(__ATTINY24A__) | \
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
defined(__ATTINY84__) | defined(__ATTINY84V__) */
// #define DDR_USI DDRA
// #define PORT_USI PORTA
// #define PIN_USI PINA
// #define PORT_USI_SDA PORTA6
// #define PORT_USI_SCL PORTA4
// #define PIN_USI_SDA PINA6
// #define PIN_USI_SCL PINA4
// #define USI_START_COND_INT USISIF
// #define USI_START_VECTOR USI_START_vect
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
//#endif
/*#if defined(__ATTINY261__) | defined(__ATTINY261A__) | \
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
defined(__ATTINY861A__) | defined(__ATTINY861A__) */
// #define DDR_USI DDRB
// #define PORT_USI PORTB
// #define PIN_USI PINB
// #define PORT_USI_SDA PORTB0
// #define PORT_USI_SCL PORTB2
// #define PIN_USI_SDA PINB0
// #define PIN_USI_SCL PINB2
// #define USI_START_COND_INT USISIF
// #define USI_START_VECTOR USI_START_vect
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
//#endif
//#if defined(__ATTINY43U__)
// #define DDR_USI DDRB
// #define PORT_USI PORTB
// #define PIN_USI PINB
// #define PORT_USI_SDA PORTB4
// #define PORT_USI_SCL PORTB6
// #define PIN_USI_SDA PINB4
// #define PIN_USI_SCL PINB6
// #define USI_START_COND_INT USISIF
// #define USI_START_VECTOR USI_START_vect
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
//#endif
//#if defined(__ATTINY87__) | defined(__ATTINY167__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB0
#define PORT_USI_SCL PORTB2
#define PIN_USI_SDA PINB0
#define PIN_USI_SCL PINB2
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_START_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
//#endif
#endif

231
TinyApp/avr3-167.ld Normal file
View file

@ -0,0 +1,231 @@
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:3)
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = 16K
data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
/* Internal text space or external memory. */
.vectors :
{
*(.vectors)
KEEP(*(.vectors))
}
.text :
{
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
*(.progmem*)
. = ALIGN(2);
__trampolines_start = . ;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = . ;
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = . ;
*(.ctors)
__ctors_end = . ;
__dtors_start = . ;
*(.dtors)
__dtors_end = . ;
KEEP(SORT(*)(.ctors))
KEEP(SORT(*)(.dtors))
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
*(.init0) /* Start here after reset. */
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
*(.fini9) /* _exit() starts here. */
KEEP (*(.fini9))
*(.fini8)
KEEP (*(.fini8))
*(.fini7)
KEEP (*(.fini7))
*(.fini6) /* C++ destructors. */
KEEP (*(.fini6))
*(.fini5)
KEEP (*(.fini5))
*(.fini4)
KEEP (*(.fini4))
*(.fini3)
KEEP (*(.fini3))
*(.fini2)
KEEP (*(.fini2))
*(.fini1)
KEEP (*(.fini1))
*(.fini0) /* Infinite loop after program termination. */
KEEP (*(.fini0))
_etext = . ;
} > text
.data : AT (ADDR (.text) + SIZEOF (.text))
{
PROVIDE (__data_start = .) ;
*(.data)
*(.data*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */
*(.gnu.linkonce.d*)
. = ALIGN(2);
_edata = . ;
PROVIDE (__data_end = .) ;
} > data
.bss : AT (ADDR (.bss))
{
PROVIDE (__bss_start = .) ;
*(.bss)
*(.bss*)
*(COMMON)
PROVIDE (__bss_end = .) ;
} > data
__data_load_start = LOADADDR(.data);
__data_load_end = __data_load_start + SIZEOF(.data);
/* Global data not cleared after reset. */
.noinit :
{
PROVIDE (__noinit_start = .) ;
*(.noinit*)
PROVIDE (__noinit_end = .) ;
_end = . ;
PROVIDE (__heap_start = .) ;
} > data
.eeprom :
{
*(.eeprom*)
__eeprom_end = . ;
} > eeprom
.fuse :
{
KEEP(*(.fuse))
KEEP(*(.lfuse))
KEEP(*(.hfuse))
KEEP(*(.efuse))
} > fuse
.lock :
{
KEEP(*(.lock*))
} > lock
.signature :
{
KEEP(*(.signature*))
} > signature
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}