Selaa lähdekoodia

Project init.

Vladimir Shilov 6 vuotta sitten
commit
9fcfe2a9a5
17 muutettua tiedostoa jossa 1396 lisäystä ja 0 poistoa
  1. 20 0
      .gitignore
  2. 670 0
      Makefile
  3. 3 0
      ReadMe.txt
  4. 17 0
      hw/ReadMe.txt
  5. BIN
      hw/cpu.dch
  6. BIN
      hw/cpu.dip
  7. BIN
      hw/disp.dch
  8. BIN
      hw/disp.dip
  9. 33 0
      inc/event-system.h
  10. 18 0
      inc/i2c.h
  11. 22 0
      inc/list_event.h
  12. 23 0
      inc/main.h
  13. 67 0
      inc/rtos.h
  14. 153 0
      src/event-system.c
  15. 115 0
      src/i2c.c
  16. 71 0
      src/main.c
  17. 184 0
      src/rtos.c

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+.dep
+build
+tmp
+*.rar
+*.zip
+*.7z
+*.DBK
+*.PWI
+*.LST
+*.SDI
+*.hex
+*.eep
+*.elf
+*.bin
+*.srec
+*.o
+*.lst
+*.map
+*.d
+*.depend

+ 670 - 0
Makefile

@@ -0,0 +1,670 @@
+# Hey Emacs, this is a -*- makefile -*-
+#----------------------------------------------------------------------------
+# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
+#
+# Released to the Public Domain
+#
+# Additional material for this makefile was written by:
+# Peter Fleury
+# Tim Henigan
+# Colin O'Flynn
+# Reiner Patommel
+# Markus Pfaff
+# Sander Pool
+# Frederik Rouleau
+# Carlos Lamas
+#
+#----------------------------------------------------------------------------
+# 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 = atmega8a
+
+
+# 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 = 16000000
+
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Target file name (without extension).
+TARGET = mnc-in12
+
+
+# Application sources directory
+#     To put object files in current directory, use a dot (.), do NOT make
+#     this an empty or blank macro!
+APP_SRC = src
+
+
+# Object files directory
+#     To put object files in current directory, use a dot (.), do NOT make
+#     this an empty or blank macro!
+OBJDIR = build/obj
+
+
+# Binary files directory
+#     To put object files in current directory, use a dot (.), do NOT make
+#     this an empty or blank macro!
+BINDIR = build
+
+
+# Search build/output directory for dependencies
+vpath %.c $(APP_SRC)
+vpath %.o .\$(OBJDIR)
+vpath %.elf .\$(BINDIR)
+vpath %.hex .\$(BINDIR)
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = $(wildcard $(APP_SRC)/*.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 = 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 = inc
+
+
+# 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 += -fshort-enums
+CFLAGS += -ffunction-sections
+CFLAGS += -fdata-sections
+#CFLAGS += -flto
+CFLAGS += -ffreestanding
+CFLAGS += -mrelax
+#CFLAGS += -fno-ivopts
+#CFLAGS += -fwhole-program
+#CFLAGS += -mcall-prologues
+#CFLAGS += -fno-split-wide-types
+CFLAGS += -W -Wall -Wextra -Wstrict-prototypes -Wundef -Werror
+#CFLAGS += -Wunreachable-code
+#CFLAGS += -Wsign-compare
+CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+CFLAGS += $(CSTANDARD)
+
+
+#---------------- 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
+CPPFLAGS += -Wundef
+CPPFLAGS += -fno-rtti
+CPPFLAGS += -fno-exceptions
+#CPPFLAGS += -mshort-calls
+#CPPFLAGS += -ffunction-sections
+#CPPFLAGS += -fdata-sections
+#CPPFLAGS += -mcall-prologues
+#CPPFLAGS += -fno-unit-at-a-time
+#CPPFLAGS += --param inline-call-cost=1
+#CPPFLAGS += -fno-split-wide-types
+#CPPFLAGS += -Wstrict-prototypes
+#CPPFLAGS += -Wunreachable-code
+#CPPFLAGS += -Wsign-compare
+#CPPFLAGS += -fvtable-gc
+CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
+CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+#CPPFLAGS += $(CSTANDARD)
+
+
+#---------------- 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),-gdwarf-2,--listing-cont-lines=100
+#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=$(BINDIR)/$(TARGET).map,--cref
+#LDFLAGS += -Wl,-static
+LDFLAGS += -Wl,-gc-sections,-flto
+#LDFLAGS += -Wl,-s
+#LDFLAGS += -Wl,-relax
+LDFLAGS += $(EXTMEMOPTS)
+LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
+LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
+#LDFLAGS += -T $(TARGET).ld
+
+
+
+#---------------- Programming Options (avrdude) ----------------
+
+# Programming hardware
+# Type: avrdude -c ?
+# to get a full listing.
+#
+AVRDUDE_PROGRAMMER = usbasp
+#AVRDUDE_PROGRAMMER = avr910
+
+# com1 = serial port. Use lpt1 to connect to parallel port.
+#AVRDUDE_PORT = com3    # programmer connected to serial device
+AVRDUDE_PORT = usb	# programmer connected to serial device
+
+# set com port baudrate
+#AVRDUDE_COM_BAUD = -b 115200
+
+AVRDUDE_WRITE_FLASH = -U flash:w:$(BINDIR)/$(TARGET).hex
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(BINDIR)/$(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
+
+AVRDUDE_MCU = m8a
+#AVRDUDE_MCU = $(MCU)
+
+# 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 $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS += $(AVRDUDE_COM_BAUD)
+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.
+AVRPATH = C:/mcu/avr-gcc/bin
+SHELL = sh
+CC = $(AVRPATH)/avr-gcc
+OBJCOPY = $(AVRPATH)/avr-objcopy
+OBJDUMP = $(AVRPATH)/avr-objdump
+SIZE = $(AVRPATH)/avr-size
+AR = $(AVRPATH)/avr-ar rcs
+NM = $(AVRPATH)/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
+#build: lib
+
+
+elf: $(BINDIR)/$(TARGET).elf
+hex: $(BINDIR)/$(TARGET).hex
+eep: $(BINDIR)/$(TARGET).eep
+lss: $(BINDIR)/$(TARGET).lss
+sym: $(BINDIR)/$(TARGET).sym
+LIBNAME=$(BINDIR)/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) $(BINDIR)/$(TARGET).hex
+#ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(BINDIR)/$(TARGET).elf
+ELFSIZE = $(SIZE) --target=elf32-avr $(BINDIR)/$(TARGET).elf
+sizebefore:
+	@if test -f $(BINDIR)/$(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
+	2>/dev/null; echo; fi
+
+sizeafter:
+	@if test -f $(BINDIR)/$(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: $(BINDIR)/$(TARGET).hex $(BINDIR)/$(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 $(BINDIR)/$(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 $(BINDIR)/$(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 \
+	$(BINDIR)/$(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: $(BINDIR)/$(TARGET).elf
+#	@echo
+	@echo $(MSG_COFF) $(BINDIR)/$(TARGET).cof
+	@$(COFFCONVERT) -O coff-avr $< $(BINDIR)/$(TARGET).cof
+
+
+extcoff: $(BINDIR)/$(TARGET).elf
+#	@echo
+	@echo $(MSG_EXTENDED_COFF) $(BINDIR)/$(TARGET).cof
+	@$(COFFCONVERT) -O coff-ext-avr $< $(BINDIR)/$(TARGET).cof
+
+
+
+# Create final output files (.hex, .eep) from ELF output file.
+%.hex: %.elf
+#	@echo
+	@echo $(MSG_FLASH) $@
+	@$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@
+
+%.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 -z $< > $@
+
+# Create a symbol table from ELF output file.
+%.sym: %.elf
+#	@echo
+	@echo $(MSG_SYMBOL_TABLE) $@
+	@$(NM) -n $< > $@
+
+
+
+# Create library from object files.
+.SECONDARY : $(BINDIR)/$(TARGET).a
+.PRECIOUS : $(OBJ)
+%.a: $(OBJ)
+#	@echo
+	@echo $(MSG_CREATING_LIBRARY) $@
+	@$(AR) $@ $(OBJ)
+
+
+# Link: create ELF output file from object files.
+.SECONDARY : $(BINDIR)/$(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) $(BINDIR)/$(TARGET).hex
+	@$(REMOVE) $(BINDIR)/$(TARGET).eep
+	@$(REMOVE) $(BINDIR)/$(TARGET).cof
+	@$(REMOVE) $(BINDIR)/$(TARGET).elf
+	@$(REMOVE) $(BINDIR)/$(TARGET).map
+	@$(REMOVE) $(BINDIR)/$(TARGET).sym
+	@$(REMOVE) $(BINDIR)/$(TARGET).lss
+	@$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
+	@$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
+	@$(REMOVE) $(CPPSRC:%.c=$(OBJDIR)/%.o)
+	@$(REMOVE) $(CPPSRC:%.c=$(OBJDIR)/%.lst)
+	@$(REMOVE) $(ASRC:%.S=$(OBJDIR)/%.o)
+	@$(REMOVE) $(ASRC:%.S=$(OBJDIR)/%.lst)
+	@$(REMOVE) $(SRC:.c=.s)
+	@$(REMOVE) $(SRC:.c=.d)
+	@$(REMOVE) $(SRC:.c=.i)
+	@$(REMOVE) $(CPPSRC:.c=.s)
+	@$(REMOVE) $(CPPSRC:.c=.d)
+	@$(REMOVE) $(CPPSRC:.c=.i)
+	@$(REMOVEDIR) .dep
+
+
+# Create object files directory
+$(shell mkdir -p $(OBJDIR)/$(APP_SRC) 2>/dev/null)
+
+# Create bin files directory
+$(shell mkdir -p $(BINDIR) 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

+ 3 - 0
ReadMe.txt

@@ -0,0 +1,3 @@
+My Nixie Clock IN-12 / Мои часы на ГРИ ИН-12
+
+Решил пустить в дело накопленное добро.

+ 17 - 0
hw/ReadMe.txt

@@ -0,0 +1,17 @@
+Вариант на ATmega8A (любая атмега от 48 по 328).
+Разъём анодов - 4 пина (PD4 - PD7).
+Адрес для дешифратора - PC0 - PC3.
+Разъёмы под DHT-22/DS18B20 (ICP1) и фоторезистор (ADC6).
+Прерывания от RTC - INT1 (PD3).
+Кнопки на линиях для программирования (PB3 - PB5).
+Линейный стабилизатор +5В из внешних 7 - 12 вольт.
+Внешний кварц.
+Добавил разъёмы для UART и I2C.
+Плата вообще жесть...
+Остались свободны два вывода (OC1A и OC1B) - но их разве что на пяточки.
+---
+заказ 17.01.2019
+подготовка - 100 грн.
+два комплектиа плат - 178.20 грн.
+всего 278.00 грн.
+Ориентировочная дата отгрузки 29.01.19г.

BIN
hw/cpu.dch


BIN
hw/cpu.dip


BIN
hw/disp.dch


BIN
hw/disp.dip


+ 33 - 0
inc/event-system.h

@@ -0,0 +1,33 @@
+//***************************************************************************
+//
+//  Author(s)...: Pashgan    http://ChipEnable.Ru
+//  Target(s)...: любой микроконтроллер mega
+//  Compiler....: IAR 5.11A
+//  Description.: Заготовка для событийной системы на таблицах
+//  Data........: 30.09.12
+//
+//***************************************************************************
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#pragma once
+#ifndef EVENT_SYSTEM_H
+#define EVENT_SYSTEM_H
+
+#include <avr/io.h>
+#include "list_event.h"
+
+/* вместимость буфера очереди событий */
+#define SIZE_BUF 16
+
+void ES_Init(es_state_t init_state);    //инициализация
+es_state_t ES_GetState(void);           //взять код состояния
+void ES_SetState(es_state_t new_state); //установить код состояния
+es_event_t ES_GetEvent(void);           //взять код события
+void ES_PlaceEvent(es_event_t event);   //разместить событие
+void ES_Dispatch(es_event_t event);     //вызов диспетчера
+
+/**
+ * ES function prototypes
+ */
+
+#endif // EVENT_SYSTEM_H

+ 18 - 0
inc/i2c.h

@@ -0,0 +1,18 @@
+#ifndef _I2C_H
+#define _I2C_H
+
+#include <avr/io.h>
+
+#define TRUE 1
+#define FALSE 0
+
+void I2CInit(void);
+void I2CClose(void);
+
+void I2CStart(void);
+void I2CStop(void);
+
+uint8_t I2CWriteByte(uint8_t data);
+uint8_t I2CReadByte(uint8_t *data,uint8_t ack);	
+
+#endif

+ 22 - 0
inc/list_event.h

@@ -0,0 +1,22 @@
+#pragma once
+#ifndef EVENT_LIST_H
+#define EVENT_LIST_H
+
+/* коды событий */
+typedef enum {
+  eventNull = 0x00,
+  evMenuWDT
+} es_event_t;
+
+/* коды состояний */
+typedef enum {
+  stNoChange = 0x00,
+  // end
+  stLastState
+} es_state_t;
+
+#ifndef NULL
+  #define NULL ((void*)0)
+#endif
+
+#endif //EVENT_LIST_H

+ 23 - 0
inc/main.h

@@ -0,0 +1,23 @@
+#pragma once
+#ifndef _MAIN_H
+#define _MAIN_H
+
+/**
+ * Áèòîâûå ìàêðîñû
+ */
+#define SetBit(x,y)    x |=  (1 << (y))
+#define ClrBit(x,y)    x &= ~(1 << (y))
+#define InvBit(x,y)    (x)^=  (1 << (y))
+#define IsBit(x,y)     (x &  (1 << (y)))
+
+#define ResBit(reg,bit)    (reg &= ~_BV(bit))
+/*
+ Àâòîìàòè÷åñêè âêëþ÷àåòñÿ avr/sfr_defs.h, êòîðûé ñîäåðæèò:
+	_BV(bit) === (1<<(bit))
+	bit_is_set(sfr, bit)
+	bit_is_clear(sfr, bit)
+	loop_until_bit_is_set(sfr, bit)
+	loop_until_bit_is_clear(sfr, bit)
+*/
+
+#endif // _MAIN_H

+ 67 - 0
inc/rtos.h

@@ -0,0 +1,67 @@
+/******************************************************************************************
+ * За основу взят планировщик задач с сайта ChipEnable.ru                                 *
+ * http://chipenable.ru/index.php/programming-avr/item/110-planirovschik.html             *
+ *                                                                                        *
+ * Доработал Шибанов Владимир aka KontAr                                                  *
+ * Дата: 26.03.2014                                                                       *
+ *                                                                                        *
+ * Изменения:                                                                             *
+ * - добавлен однократный вызов задачи                                                    *
+ * - добавлено удаление задачи по имени                                                   *
+ * - при повторном добавлении задачи обновляются ее переменные                            *
+ * - добавлен указатель на "хвост" списка                                                 *
+ * - функции РТОС скорректированы с учетом "хвоста"                                       *
+ ******************************************************************************************
+ * shilov, 2015.04.07									  *
+ * совместил с модулем милисекундных задержек на таймере				  *
+ ******************************************************************************************/
+#pragma once
+#ifndef RTOS_H
+#define RTOS_H
+
+#include <avr/io.h>
+
+#define MAX_TASKS      10              // Количество задач
+
+/**
+ * Будем использовать таймер 0, период -- 1 мсек
+ */
+#define TIMER_HZ		1000
+#define TIMER_PRESCALER 64
+#define	TIMER_CNT		(0x100 - (F_CPU / TIMER_PRESCALER / TIMER_HZ))
+
+#define TIMER_TCCR		TCCR0
+#define TIMER_TCNT		TCNT0
+#define TIMER_TIMSK		TIMSK
+#define TIMER_CSB		(1<<CS02)
+#define TIMER_INT		(1<<TOIE0)
+#define TIMER_OVF_VECT	TIMER0_OVF_vect
+
+/**
+ * Структура задачи
+ */
+typedef struct task
+{
+   void (*pFunc) (void);  // указатель на функцию
+   uint16_t delay;  // задержка перед первым запуском задачи
+   uint16_t period; // период запуска задачи
+   uint8_t run;     // флаг готовности задачи к запуску
+} task;
+
+/**
+ * Прототипы фукнций
+ */
+void RTOS_Init (void);
+void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod);
+void RTOS_DeleteTask (void (*taskFunc)(void));
+void RTOS_DispatchTask (void);
+void RTOS_Timer (void);
+
+void tdelay_ms(uint16_t msek);
+
+inline void tdelay_us(uint16_t usek) {
+  TCNT1 = 0;
+  while (TCNT1 < usek) {};
+}
+
+#endif

+ 153 - 0
src/event-system.c

@@ -0,0 +1,153 @@
+//***************************************************************************
+//
+//  Author(s)...: Pashgan    http://ChipEnable.Ru
+//  Target(s)...: любой микроконтроллер mega
+//  Compiler....: IAR 5.11A
+//  Description.: Заготовка для событийной системы на таблицах
+//  Data........: 30.09.12
+//
+//***************************************************************************
+#include "event-system.h"
+#include <avr/pgmspace.h>
+
+/* функция-заглушка */
+static void EmptyFunc(void);
+
+/* кольцевой буфер */
+static volatile es_event_t cycleBuf[SIZE_BUF];
+static volatile uint8_t tailBuf = 0;
+static volatile uint8_t headBuf = 0;
+static volatile uint8_t countBuf = 0;
+
+static volatile es_state_t _State;
+
+typedef struct {
+    es_state_t startState;
+    es_state_t endState;
+    es_event_t startEvent;
+    es_event_t endEvent;
+    es_state_t nextstate;
+    void (*pStateFunc1)(void);
+    void (*pStateFunc2)(void);
+} table_state_t;
+
+/** таблица состояний */
+const table_state_t table[] = {
+/* STATE from   STATE to     EVENT from       EVENT to         NEXT STATE   STATE_FUNC1   STATE_FUNC2 */
+
+  /* обязательная пустая строка таблицы */
+  {stNoChange, stNoChange, eventNull, eventNull, stNoChange, EmptyFunc, EmptyFunc}
+};
+
+/**
+  * @brief  Take event.
+  * @param  None
+  * @retval Event
+  */
+es_event_t ES_GetEvent(void)
+{
+  es_event_t event;
+  if (countBuf > 0){
+    event = cycleBuf[headBuf];
+    countBuf--;
+    headBuf = (headBuf + 1) & (SIZE_BUF - 1);
+    return event;
+  }
+  return eventNull;
+}
+
+/**
+  * @brief  Place event.
+  * @param  Event
+  * @retval None
+  */
+void ES_PlaceEvent(es_event_t event)
+{
+  if (countBuf < SIZE_BUF){
+      cycleBuf[tailBuf] = event;
+      tailBuf = (tailBuf + 1) & (SIZE_BUF - 1);
+      countBuf++;
+  /* сигнализация переполнения буфера событий */
+  } else {
+      while(1);
+  }
+}
+
+/**
+  * @brief  Initialize event system.
+  * @param  Start Event
+  * @retval None
+  */
+void ES_Init(es_state_t init_state)
+{
+  tailBuf = 0;
+  headBuf = 0;
+  countBuf = 0;
+  _State = init_state;
+}
+
+/**
+  * @brief  Fake function.
+  * @param  None
+  * @retval None
+  */
+static void EmptyFunc(void)
+{
+}
+
+/* макросы для чтения флэш памяти */
+#define prb(data) pgm_read_byte(&(data))
+#define prw(data) pgm_read_word(&(data))
+
+/**
+  * @brief  Dispatcher of event system.
+  * @param  Event
+  * @retval None
+  */
+void ES_Dispatch(es_event_t event)
+{
+    void (*pStateFunc1)(void);
+    void (*pStateFunc2)(void);
+    uint8_t i;
+
+    pStateFunc1 = NULL;
+    pStateFunc2 = NULL;
+
+    //определяем следующее состояние
+    for (i=0; prb(table[i].startEvent) || prb(table[i].endEvent); i++)
+    {
+        //если текущее состояние попадает в диапазон
+        if ( (_State >= prb(table[i].startState)) && (_State <= prb(table[i].endState)) ) {
+          //если поступившее событие попадает в диапазон
+          if((event >= prb(table[i].startEvent)) && (event <= prb(table[i].endEvent)) ) {
+            //меняем состояние если требуется
+            if (prb(table[i].nextstate) != stNoChange) {
+              _State = prb(table[i].nextstate);
+            }
+            pStateFunc1 = (void *)prw(table[i].pStateFunc1);
+            pStateFunc2 = (void *)prw(table[i].pStateFunc2);
+            break;
+          }
+        }
+    }
+    if (pStateFunc1) pStateFunc1();
+    if (pStateFunc2) pStateFunc2();
+}
+
+/**
+  * @brief  Return current state code.
+  * @param  None
+  * @retval Event
+  */
+es_state_t ES_GetState(void) {
+  return _State;
+}
+
+/**
+  * @brief  Set current state to given code .
+  * @param  Event
+  * @retval None
+  */
+void ES_SetState(es_state_t new_state) {
+  _State = new_state;
+}

+ 115 - 0
src/i2c.c

@@ -0,0 +1,115 @@
+/****************************************************
+Low Level I2C Data Transreceiveing APIs
+
+PLEASE SEE WWW.EXTREMEELECTRONICS.CO.IN FOR DETAILED
+SCHEMATICS,USER GUIDE AND VIDOES.
+
+COPYRIGHT (C) 2008-2009 EXTREME ELECTRONICS INDIA
+****************************************************/
+
+#include <avr/io.h>
+#include "i2c.h"
+
+#define TWI_TIMEOUT    50
+uint8_t TWI_WDT;
+
+void I2CInit(void) {
+  //Set up TWI Module
+  TWBR = 32;
+  //TWSR |=((1<<TWPS1)|(1<<TWPS0));
+
+  //Enable the TWI Module
+  TWCR|=(1<<TWEN);
+}
+
+void I2CClose(void)
+{
+  //Disable the module
+  TWCR&=(~(1<<TWEN));
+}
+
+void I2CStart(void) {
+  //Put Start Condition on Bus
+  TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
+
+  //Poll Till Done
+  TWI_WDT = TWI_TIMEOUT;
+  while(!(TWCR & (1<<TWINT)) && (TWI_WDT > 0));
+}
+
+void I2CStop(void) {
+  //Put Stop Condition on bus
+  TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
+
+  //Wait for STOP to finish
+  // зачем это ждать тут? проверять перед стартом и всё!
+  TWI_WDT = TWI_TIMEOUT;
+  while(TWCR & (1<<TWSTO) && (TWI_WDT > 0));
+}
+
+uint8_t I2CWriteByte(uint8_t data) {
+
+  TWDR=data;
+
+  //Initiate Transfer
+  TWCR=(1<<TWEN)|(1<<TWINT);
+
+  //Poll Till Done
+  TWI_WDT = TWI_TIMEOUT;
+  while(!(TWCR & (1<<TWINT))) {
+    if (0 == TWI_WDT) {
+      return -2;
+    }
+  }
+
+  //Check Status
+  if((TWSR & 0xF8) == 0x18 || (TWSR & 0xF8) == 0x28 || (TWSR & 0xF8) == 0x40) {
+    //SLA+W Transmitted and ACK received
+    //or
+    //SLA+R Transmitted and ACK received
+    //or
+    //DATA Transmitted and ACK recived
+
+    return TRUE;
+  } else {
+    return FALSE;  //Error
+  }
+}
+
+uint8_t I2CReadByte(uint8_t *data,uint8_t ack) {
+  //Set up ACK
+  if(ack) {
+    //return ACK after reception
+    TWCR|=(1<<TWEA);
+  } else {
+    //return NACK after reception
+    //Signals slave to stop giving more data
+    //usually used for last byte read.
+    TWCR&=(~(1<<TWEA));
+  }
+
+  //Now enable Reception of data by clearing TWINT
+  TWCR|=(1<<TWINT);
+
+  //Wait till done
+  TWI_WDT = TWI_TIMEOUT;
+  while(!(TWCR & (1<<TWINT))) {
+    if (0 == TWI_WDT) {
+      return -2;
+    }
+  }
+
+  //Check status
+  if((TWSR & 0xF8) == 0x58 || (TWSR & 0xF8) == 0x50) {
+    //Data received and ACK returned
+    //  or
+    //Data received and NACK returned
+
+    //Read the data
+
+    *data=TWDR;
+    return TRUE;
+  } else {
+    return FALSE;  //Error
+  }
+}

+ 71 - 0
src/main.c

@@ -0,0 +1,71 @@
+/**
+ * My Nixie Clock IN-12
+ * Vladimir N. Shilov <shilow@ukr.net>
+ * 2019.01.18
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#include "main.h"
+#include "i2c.h"
+//#include "ds3231.h"
+#include "rtos.h"
+#include "event-system.h"
+
+void main(void) {
+  /**
+   * Локальные переменные
+   */
+  uint8_t event = 0;
+
+  /**
+   * Инициализация, настройка...
+   */
+  // выкл. аналог. компаратор
+  ResBit(ACSR,ACD);
+
+  // Разрешим прерывания
+  sei();
+
+  // Init Scheduler and TDelay
+  RTOS_Init();
+
+  //Initialize I2C Bus
+  I2CInit();
+
+  ES_Init(stNoChange);
+
+  /** main loop */
+  do {
+
+    // крутим диспетчер
+    RTOS_DispatchTask();
+
+    event = ES_GetEvent();
+    if (event) {
+      ES_Dispatch(event);
+    }
+
+  } while(1);
+}
+
+/**
+ *  П р е р ы в а н и я
+ */
+
+/* от часов */
+ISR (INT0_vect) {
+	//RTOS_SetTask(GetTimeDate,0,0);
+}
+
+
+/**
+ * заглушка для неиспользуемых прерываний
+ */
+ISR(__vector_default,ISR_NAKED) {
+	reti();
+}

+ 184 - 0
src/rtos.c

@@ -0,0 +1,184 @@
+#include <avr/sleep.h>
+#include <avr/interrupt.h>
+#include "rtos.h"
+
+static volatile uint8_t saveRegister;
+#define  ENABLE_INTERRUPT sei()
+#define DISABLE_INTERRUPT saveRegister = SREG; cli()
+#define RESTORE_INTERRUPT SREG = saveRegister
+//использовать RESTORE только после DISABLE
+
+/*
+ * Переменные модуля
+ */
+static volatile task TaskArray[MAX_TASKS]; // очередь задач
+static volatile uint8_t arrayTail;         // "хвост" очереди
+// внешние переменные
+extern uint8_t TWI_WDT;
+
+// счётчик задержки
+static volatile uint16_t TDelay;
+
+/*
+ * Инициализация РТОС и t_delay, время тика - 1 мс
+ */
+inline void RTOS_Init()
+{
+  // настраиваем основной таймер
+  TIMER_TCCR = TIMER_CSB;
+  TIMER_TCNT = TIMER_CNT;
+  TIMER_TIMSK |= TIMER_INT;
+
+  // микросекундный таймер
+  // prescaler = 8
+  TCCR1B = ((CS12<<0) | (CS11<<1) | (CS10<<0));
+  // interrupt -- not used
+  // set counter to 0
+  TCNT1 = 0;
+  // "хвост" в 0
+  arrayTail = 0;
+}
+
+/*
+ * Добавление задачи в список
+ */
+void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod)
+{
+   uint8_t i;
+
+   if(!taskFunc) return;
+   for(i = 0; i < arrayTail; i++)                     // поиск задачи в текущем списке
+   {
+      if(TaskArray[i].pFunc == taskFunc)              // если нашли, то обновляем переменные
+      {
+         DISABLE_INTERRUPT;
+
+         TaskArray[i].delay  = taskDelay;
+         TaskArray[i].period = taskPeriod;
+         TaskArray[i].run    = 0;
+
+         RESTORE_INTERRUPT;
+         return;                                      // обновив, выходим
+      }
+   }
+
+   if (arrayTail < MAX_TASKS)                         // если такой задачи в списке нет
+   {                                                  // и есть место,то добавляем
+      DISABLE_INTERRUPT;
+
+      TaskArray[arrayTail].pFunc  = taskFunc;
+      TaskArray[arrayTail].delay  = taskDelay;
+      TaskArray[arrayTail].period = taskPeriod;
+      TaskArray[arrayTail].run    = 0;
+
+      arrayTail++;                                    // увеличиваем "хвост"
+      RESTORE_INTERRUPT;
+   }
+}
+
+/*
+ * Удаление задачи из списка
+ */
+inline void RTOS_DeleteTask (void (*taskFunc)(void))
+{
+   uint8_t i;
+
+   for (i=0; i<arrayTail; i++)                        // проходим по списку задач
+   {
+      if(TaskArray[i].pFunc == taskFunc)              // если задача в списке найдена
+      {
+
+         DISABLE_INTERRUPT;
+         if(i != (arrayTail - 1))                     // переносим последнюю задачу
+         {                                            // на место удаляемой
+            TaskArray[i] = TaskArray[arrayTail - 1];
+         }
+         arrayTail--;                                 // уменьшаем указатель "хвоста"
+         RESTORE_INTERRUPT;
+         return;
+      }
+   }
+}
+
+/*
+ * Диспетчер РТОС, вызывается в main
+ */
+
+void RTOS_DispatchTask(void)
+{
+   uint8_t i;
+   void (*function) (void);
+   for (i=0; i<arrayTail; i++)                        // проходим по списку задач
+   {
+      if (TaskArray[i].run == 1)                      // если флаг на выполнение взведен,
+      {                                               // запоминаем задачу, т.к. во
+         function = TaskArray[i].pFunc;               // время выполнения может
+                                                      // измениться индекс
+         if(TaskArray[i].period == 0)
+         {                                            // если период равен 0
+            RTOS_DeleteTask(TaskArray[i].pFunc);      // удаляем задачу из списка,
+
+         }
+         else
+         {
+            TaskArray[i].run = 0;                     // иначе снимаем флаг запуска
+            if(!TaskArray[i].delay)                   // если задача не изменила задержку
+            {                                         // задаем ее
+               TaskArray[i].delay = TaskArray[i].period-1;
+            }                                         // задача для себя может сделать паузу
+         }
+         (*function)();                               // выполняем задачу
+      }
+   }
+}
+
+/*
+ * Delay, msek
+ * также, что-бы зря не терять время -- крутим диспетчер
+ */
+void tdelay_ms(uint16_t msek) {
+
+  TDelay = msek;
+
+  do {
+    RTOS_DispatchTask();
+    // делать нехрен -- спим, ждём прерывание
+    set_sleep_mode(SLEEP_MODE_IDLE);
+    sleep_mode();
+  } while (TDelay>0);
+
+}
+
+/******************************************************************************************
+ * Таймерная служба РТОС и tdelay (прерывание аппаратного таймера)
+ */
+ISR(TIMER_OVF_VECT) {
+
+  // перезарядим таймер
+  TIMER_TCNT = TIMER_CNT;
+
+  /* RTOS_Timer */
+  uint8_t i;
+
+  // проходим по списку задач
+  for (i=0; i<arrayTail; i++) {
+    // если время до выполнения истекло
+    if (TaskArray[i].delay == 0) {
+      // взводим флаг запуска,
+      TaskArray[i].run = 1;
+    } else {
+      // иначе уменьшаем время
+      TaskArray[i].delay--;
+    }
+  }
+
+  /* TDelay_Timer -- уменьшим счётчик */
+  if (TDelay > 0) {
+    TDelay --;
+  }
+
+  if (TWI_WDT > 0) {
+    TWI_WDT --;
+  }
+
+}