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:
parent
3179dd1d41
commit
b4a9d62b22
5 changed files with 2164 additions and 0 deletions
206
TinyApp/Common_Define.h
Normal file
206
TinyApp/Common_Define.h
Normal 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
624
TinyApp/Makefile
Normal 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
929
TinyApp/TinyApp.c
Normal 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
174
TinyApp/USI_TWI_Slave.h
Normal 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
231
TinyApp/avr3-167.ld
Normal 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) }
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue