aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2016-03-08 16:10:33 +0100
committerKarel Kočí <cynerd@email.cz>2016-03-08 16:10:33 +0100
commit5d29fe79d30f430ae326d9dc57ccfaed6fe61328 (patch)
tree8341804d561c0060176cbebc3f9a57c7c07f7816
parent4e773191d447ac434536262a6f204dd991d4ad77 (diff)
downloadavr-ioe-5d29fe79d30f430ae326d9dc57ccfaed6fe61328.tar.gz
avr-ioe-5d29fe79d30f430ae326d9dc57ccfaed6fe61328.tar.bz2
avr-ioe-5d29fe79d30f430ae326d9dc57ccfaed6fe61328.zip
Another full update of current work
-rw-r--r--.gitignore2
-rw-r--r--.gitmodules3
-rw-r--r--Kconfig152
-rw-r--r--Makefile145
-rw-r--r--README.md10
-rw-r--r--adc.h9
-rw-r--r--avr-ioe.mk62
-rw-r--r--can_mcp2515.h14
-rw-r--r--docs/add_support.md (renamed from src/can_mcp2515.c)0
-rw-r--r--docs/index.md10
-rw-r--r--docs/modules/ioport.md153
-rw-r--r--docs/modules/spi.md (renamed from doc/spi.md)26
-rw-r--r--docs/modules/tasks.md37
-rw-r--r--docs/modules/timer.md0
-rw-r--r--docs/modules/usart.md0
-rw-r--r--docs/modules/utils/buffer.md105
-rw-r--r--docs/modules/utils/narray.md64
-rw-r--r--docs/usage.md0
-rw-r--r--examples/blink/Makefile64
-rw-r--r--examples/blink/README.md0
-rw-r--r--examples/blink/blink.c14
-rw-r--r--examples/blink/config24
-rw-r--r--examples/blink/config.orig24
-rw-r--r--examples/spiblink/Makefile66
-rw-r--r--examples/spiblink/config23
-rw-r--r--examples/spiblink/config.orig23
-rw-r--r--examples/spiblink/makefile32
-rw-r--r--examples/spiblink/master.c2
-rw-r--r--examples/spiblink/slave.c2
-rw-r--r--examples/usartecho/Makefile64
-rw-r--r--examples/usartecho/config41
-rw-r--r--examples/usartecho/config.orig41
-rw-r--r--examples/usartecho/echo.c2
-rw-r--r--examples/usartecho/makefile36
-rw-r--r--include/adc.h15
-rw-r--r--include/avr-ioe.h (renamed from avr-ioe.h)1
-rw-r--r--include/can/global.h20
-rw-r--r--include/can/mcp2515.h36
-rw-r--r--include/can/software.h9
-rw-r--r--include/ioport.h55
-rw-r--r--include/mcu/Kconfig11
-rw-r--r--include/mcu/atmega328p.Kconfig8
-rw-r--r--include/mcu/atmega328p.h63
-rw-r--r--include/mcu/atmega32u4.h (renamed from mcu/ATmega32U4.h)0
-rw-r--r--include/mcu/atmega8a.h (renamed from mcu/ATmega8A.h)0
-rw-r--r--include/mcu/attiny4313.h46
-rw-r--r--include/mcu/attiny85.Kconfig4
-rw-r--r--include/mcu/attiny85.h (renamed from mcu/ATtiny85.h)13
-rw-r--r--include/mcu/mcu.h (renamed from mcu/mcu.h)0
-rw-r--r--include/mcu/mcu_def.h (renamed from mcu/mcu_def.h)10
-rw-r--r--include/pwm.h (renamed from pwm.h)0
-rw-r--r--include/sensors/dht22.h (renamed from sensor_dht22.h)7
-rw-r--r--include/spi.h (renamed from spi.h)25
-rw-r--r--include/tasks.h94
-rw-r--r--include/timer.h28
-rw-r--r--include/twi.h (renamed from twi.h)1
-rw-r--r--include/usart.h (renamed from usart.h)38
-rw-r--r--include/usi_spi.h (renamed from usi_spi.h)0
-rw-r--r--include/utils/buffer.h (renamed from buffers.h)44
-rw-r--r--include/utils/narray.h21
-rw-r--r--include/utils/timers_div.h81
-rw-r--r--include/wireless/nrf24l01p.h0
m---------kconfig0
-rw-r--r--makefile16
-rw-r--r--mcu/ATmega328P.h29
-rw-r--r--mcu/ATtiny4313.h17
-rw-r--r--mkdocs.yml20
-rw-r--r--src/adc.c4
-rw-r--r--src/can/mcp2515.c52
-rw-r--r--src/ioport.c113
-rw-r--r--src/pcint.c32
-rw-r--r--src/sensors/dht22.c (renamed from src/sensor_dht22.c)2
-rw-r--r--src/spi.c24
-rw-r--r--src/tasks.c64
-rw-r--r--src/timer.c130
-rw-r--r--src/usart.c131
-rw-r--r--src/usi_spi.c4
-rw-r--r--src/utils/buffer.c70
-rw-r--r--src/utils/narray.c36
-rw-r--r--tasks.h44
-rw-r--r--template/Makefile72
-rw-r--r--template/README.md9
l---------template/avr-ioe1
-rw-r--r--template/main.c5
-rw-r--r--time.h15
-rw-r--r--timer.h147
86 files changed, 2292 insertions, 625 deletions
diff --git a/.gitignore b/.gitignore
index 19ddade..a7c9ab6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,11 @@
*~
.*
!/.gitignore
+!/.gitmodules
*.o
*.d
*.hex
*.elf
trash
+libioe.a
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..a8be02a
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "kconfig"]
+ path = kconfig
+ url = https://github.com/guillon/kconfig.git
diff --git a/Kconfig b/Kconfig
new file mode 100644
index 0000000..55d10f3
--- /dev/null
+++ b/Kconfig
@@ -0,0 +1,152 @@
+mainmenu "AVR-IOE configuration"
+
+source "include/mcu/Kconfig"
+
+config F_CPU
+ int "CPU frequency in kHz (F_CPU)"
+ default 16000
+
+# Toolchain #####################################################################
+
+menu "Compilation options"
+
+config GNUTOOLCHAIN_PREFIX
+ string "GNU Toolchain prefix"
+ default "avr-"
+
+config CONFCFLAGS
+ string "Compilation CFlags"
+ default "-Os -ffunction-sections -fdata-sections -fshort-enums -Wall"
+
+endmenu
+
+# IO Ports ######################################################################
+
+config MCUSUPPORT_IOPORTS
+ bool
+ default n
+
+config CONFIG_IOPORTS
+ bool "Input/Output ports"
+ default y
+ depends on MCUSUPPORT_IOPORTS
+
+config MCUSUPPORT_PCINT0
+ bool
+ default n
+config MCUSUPPORT_PCINT1
+ bool
+ default n
+config MCUSUPPORT_PCINT2
+ bool
+ default n
+
+config CONFIG_IOPORTS_PCINT
+ bool "Input/Output ports change interrupts"
+ depends on CONFIG_IOPORTS
+ depends on MCUSUPPORT_PCINT0 || MCUSUPPORT_PCINT1 || MCUSUPPORT_PCINT2
+
+# SPI ###########################################################################
+
+config MCUSUPPORT_SPI
+ bool
+ default n
+
+config CONFIG_SPI
+ bool "Serial peripheral interface"
+ depends on MCUSUPPORT_SPI
+
+# USART #########################################################################
+config MCUSUPPORT_USART
+ bool
+ default n
+
+menuconfig CONFIG_USART
+ bool "Universal synchronous/asynchronous transceiver"
+ depends on MCUSUPPORT_USART
+
+if CONFIG_USART
+
+config CONFIG_USART_BAUD
+ int "Baudrate"
+ default 115200
+
+choice USART_PARITY_C
+ prompt "Parity"
+config USART_PARITY_C_NONE
+ bool "None"
+config USART_PARITY_C_ODD
+ bool "Odd"
+config USART_PARITY_C_EVEN
+ bool "Even"
+endchoice
+config CONFIG_USART_PARITY
+ string
+ default "USART_PARITY_NONE" if USART_PARITY_C_NONE
+ default "USART_PARITY_ODD" if USART_PARITY_C_ODD
+ default "USART_PARITY_EVEN" if USART_PARITY_C_EVEN
+
+config CONFIG_USART_DATABITS
+ int "Data bits"
+ default 8
+
+choice USART_STOPBIT_C
+ prompt "Stop bit"
+config USART_STOPBIT_C_SINGLE
+ bool "Single"
+config USART_STOPBIT_C_DOUBLE
+ bool "Double"
+endchoice
+config CONFIG_USART_STOPBIT
+ string
+ default "USART_STOPBIT_SINGLE" if USART_STOPBIT_C_SINGLE
+ default "USART_STOPBIT_DOUBLE" if USART_STOPBIT_C_DOUBLE
+
+config CONFIG_USART_OUTPUT_BUFFER
+ bool "Use output buffer"
+ default n
+
+config CONFIG_USART_OUTBUFFER_SIZE
+ int "Output buffer size in bytes." if CONFIG_USART_OUTPUT_BUFFER
+ default 0 if CONFIG_USART_OUTPUT_BUFFER
+ default 32
+
+choice USART_OUTBUFFER_MODE_C
+ prompt "Output buffer replacement policy" if CONFIG_USART_OUTPUT_BUFFER
+config USART_OUTBUFFER_MODE_C_BLOCK
+ bool "Block"
+config USART_OUTBUFFER_MODE_C_OVERWRITE
+ bool "Overwrite"
+config USART_OUTBUFFER_MODE_C_DROP
+ bool "Drop"
+endchoice
+config CONFIG_USART_OUTBUFFER_MODE
+ int
+ default 1 if USART_OUTBUFFER_MODE_C_OVERWRITE
+ default 2 if USART_OUTBUFFER_MODE_C_DROP
+ default 0
+
+config CONFIG_USART_INPUT_BUFFER
+ bool "Use input buffer"
+
+config CONFIG_USART_INBUFFER_SIZE
+ int "Input buffer size in bytes." if CONFIG_USART_INPUT_BUFFER
+ default 0 if CONFIG_USART_INPUT_BUFFER
+ default 32
+
+choice USART_INBUFFER_MODE_C
+ prompt "Input buffer replacement policy" if CONFIG_USART_INPUT_BUFFER
+config USART_INBUFFER_MODE_C_BLOCK
+ bool "Block"
+config USART_INBUFFER_MODE_C_OVERWRITE
+ bool "Overwrite"
+config USART_INBUFFER_MODE_C_DROP
+ bool "Drop"
+endchoice
+config CONFIG_USART_INBUFFER_MODE
+ int
+ default 1 if USART_INBUFFER_MODE_C_OVERWRITE
+ default 2 if USART_INBUFFER_MODE_C_DROP
+ default 0
+
+endif
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..57c4095
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,145 @@
+MAKEFLAGS += --no-builtin-rules
+
+SRC = src/spi.c \
+ src/usart.c \
+ src/timer.c \
+ src/tasks.c \
+ src/ioport.c \
+ src/sensors/dht22.c \
+
+OBJ = $(patsubst %.c,%.o,$(SRC))
+DEP = $(patsubst %.c,%.d,$(SRC))
+
+# default configuration path. Can be changed by enviroment to build with
+# separate configuration files.
+CONFIG ?= .config
+
+.PHONY: all
+# Check if we have configuration"
+ifneq ("$(wildcard $(CONFIG))","")
+all: libioe.a
+else
+all: help $(CONFIG)
+endif
+
+$(CONFIG):
+ @echo Please generate configuration first using config or menuconfig target
+ @exit 1
+
+.PHONY: oldconfig
+oldconfig:
+ @[ ! -f "$(CONFIG)" ] || [ ! -f "$(CONFIG).orig" ] || mv "$(CONFIG).orig" config
+ @$(MAKE) -f kconfig/GNUmakefile --no-print-directory \
+ TOPDIR=. SRCDIR=kconfig oldconfig
+ @[ ! -f config ] || sed 's/="\(.*\)"/=\1/' config > "$(CONFIG)"
+ @[ ! -f config ] || mv config "$(CONFIG).orig"
+ @[ ! -f config.old ] || mv config.old "$(CONFIG).old"
+
+.PHONY: config
+config:
+ @[ ! -f "$(CONFIG)" ] || [ ! -f "$(CONFIG).orig" ] || mv "$(CONFIG).orig" config
+ @$(MAKE) -f kconfig/GNUmakefile --no-print-directory \
+ TOPDIR=. SRCDIR=kconfig config
+ @[ ! -f config ] || sed 's/="\(.*\)"/=\1/' config > "$(CONFIG)"
+ @[ ! -f config ] || mv config "$(CONFIG).orig"
+ @[ ! -f config.old ] || mv config.old "$(CONFIG).old"
+
+.PHONY: menuconfig
+menuconfig:
+ @[ ! -f "$(CONFIG)" ] || [ ! -f "$(CONFIG).orig" ] || mv "$(CONFIG).orig" config
+ @$(MAKE) -f kconfig/GNUmakefile --no-print-directory \
+ TOPDIR=. SRCDIR=kconfig menuconfig
+ @[ ! -f config ] || sed 's/="\(.*\)"/=\1/' config > "$(CONFIG)"
+ @[ ! -f config ] || mv config "$(CONFIG).orig"
+ @[ ! -f config.old ] || mv config.old "$(CONFIG).old"
+# Note about this file moving madness:
+# avr-ioe is using Kconfig for configuration and it is not prepared too well for
+# nested projects (at least I don't know way). This unfortunately means that to
+# have configuration in parent project, We have to move it every time we are
+# generating it. Also upper projects can't use Kconfig for its self configuration.
+
+# Check if we have configuration"
+ifneq ("$(wildcard $(CONFIG))","")
+ifeq (,$(findstring clean,$(MAKECMDGOALS)))
+ifeq (,$(findstring help,$(MAKECMDGOALS)))
+ifeq (,$(findstring docs,$(MAKECMDGOALS)))
+ifeq (,$(findstring serve-docs,$(MAKECMDGOALS)))
+ifeq (,$(findstring clean-docs,$(MAKECMDGOALS)))
+
+include $(CONFIG)
+-include $(DEP)
+
+CFLAGS = $(shell echo $(CONFCFLAGS)) $(shell echo -DF_CPU=$(F_CPU)000L) \
+ -mmcu=$(MMCU) -Iinclude -imacros .config.h
+GCC = $(GNUTOOLCHAIN_PREFIX)gcc
+AR = $(GNUTOOLCHAIN_PREFIX)ar
+
+libioe.a: $(OBJ)
+ @echo " AR $@"
+ @$(AR) -crs $@ $^
+
+$(OBJ): %.o: %.c .config.h
+ @echo " CC $@"
+ @$(GCC) $(CFLAGS) -c -o $@ $<
+
+$(DEP): %.d: %.c .config.h
+ @echo " DEP $@"
+ @$(GCC) -MM -MG -MT '$*.o $@' $(CFLAGS) -c -o $@ $<
+
+.config.h: $(CONFIG)
+ @echo " GEN .config.h"
+ @grep -v "^#" $(CONFIG) | grep "CONFIG_" | sed 's/=/ /;s/^/#define /' > $@
+# This is not optimal because configuration change results to complete project
+# rebuild instead of only rebuilding required files.
+
+endif
+endif
+endif
+endif
+endif
+else
+
+libioe.a:
+ @echo Please generate configuration first using config or menuconfig target
+
+endif
+
+.PHONY: clean
+clean:
+ @echo " CLEAN OBJ"
+ @$(RM) $(OBJ)
+ @echo " CLEAN DEP"
+ @$(RM) $(DEP) .config.h
+ @echo " CLEAN libioe.a"
+ @$(RM) libioe.a
+
+.PHONY: docs
+docs:
+ @echo " DOC $@"
+ @mkdocs build
+
+
+.PHONY: serve-docs
+serve-docs:
+ @mkdocs serve
+
+.PHONY: clean-docs
+clean-docs:
+ @echo " CLEAN docs"
+ @$(RM) -r site
+
+.PHONY: distclean
+distclean: clean clean-docs
+ @echo " CLEAN CONFIG"
+ @$(RM) $(CONFIG) $(CONFIG).orig
+
+.PHONY: help
+help:
+ @echo "all/libioe.a - Build library"
+ @echo "config - Start configuration program"
+ @echo "menuconfig - NCurses based configuration program"
+ @echo "docs - Build documentation"
+ @echo "server-docs - Start temporally http server with documentation"
+ @echo "help - Prints this text"
+ @echo "clean - Removing all object files generated from source files"
+ @echo "clean-docs - Remove generated documentation"
diff --git a/README.md b/README.md
index 17d3110..2682fb9 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,13 @@
#AVR-IOE
##AVR input/output expansion
-This is package of code for SPI, TWI and USART interfaces from AVR
-micro-controllers.
+This is library that implements different input/output interfaces and other
+utilities. Its target is to create simple and highly configurable pack of code for
+simplifying development for AVR micro-controllers.
Code is targeted for five different chips, ATmega328p, ATmega32u4, ATmega8A,
ATtiny4313 and ATtiny85. But support for more chips can be added.
+
+### Getting started
+To use this library, you have to create new project (you can copy template
+directory). Then copy/clone this repository to your project. For more information
+see file `doc/usage.md`.
diff --git a/adc.h b/adc.h
deleted file mode 100644
index 3eaea41..0000000
--- a/adc.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <stdint.h>
-
-#ifndef _IOE_ADC_H_
-#define _IOE_ADC_H_
-
-
-#endif /* _IOE_ADC_H_ */
diff --git a/avr-ioe.mk b/avr-ioe.mk
deleted file mode 100644
index fb818e8..0000000
--- a/avr-ioe.mk
+++ /dev/null
@@ -1,62 +0,0 @@
-ifndef IOE_PREFIX
- IOE_PREFIX = .
-endif
-
-IOE_SRC = $(IOE_PREFIX)/src/spi.c \
- $(IOE_PREFIX)/src/usart.c \
- $(IOE_PREFIX)/src/timer.c \
- $(IOE_PREFIX)/src/tasks.c \
- $(IOE_PREFIX)/src/pcint.c \
- $(IOE_PREFIX)/src/sensor_dht22.c \
-
-IOE_OBJ = $(patsubst %.c,%.o,$(IOE_SRC))
-IOE_DEP = $(patsubst %.c,%.d,$(IOE_SRC))
-
-
-ifndef IOE_ONLYPATHS # Following section can be suppressed by defining this variable
-
-ifneq ($(MAKECMDGOALS),clean)
-ifneq ($(MAKECMDGOALS),help)
--include $(IOE_DEP)
-endif
-endif
-
-ifndef F_CPU
- $(error Please define F_CPU variable in makefile before including avr-ioe.mk)
-endif
-ifndef MMCU
- $(error Pleade define MMCU variable in makefile before including avr-ioe.mk)
-endif
-IOE_CFLAGS ?= -Os -ffunction-sections -fdata-sections -fshort-enums -Wall \
- -DF_CPU=$(F_CPU) -mmcu=$(MMCU)
-IOE_GCC ?= avr-gcc
-
-ifndef IOE_SHORTOUTPUT
-$(IOE_OBJ): %.o: %.c
- $(IOE_GCC) $(IOE_CFLAGS) -c -o $@ $<
-
-$(IOE_DEP): %.d: %.c
- $(IOE_GCC) -MM -MG -MT '$*.o $@' $(IOE_CFLAGS) -c -o $@ $<
-
-.PHONY: ioeclean
-ioeclean::
- $(RM) $(IOE_OBJ)
- $(RM) $(IOE_DEP)
-else
-$(IOE_OBJ): %.o: %.c
- @echo " IOE CC $@"
- @$(IOE_GCC) $(IOE_CFLAGS) -c -o $@ $<
-
-$(IOE_DEP): %.d: %.c
- @echo " IOE DEP $@"
- @$(IOE_GCC) -MM -MG -MT '$*.o $@' $(IOE_CFLAGS) -c -o $@ $<
-
-.PHONY: ioeclean
-ioeclean::
- @echo " IOE CLEAN OBJ"
- @$(RM) $(IOE_OBJ)
- @echo " IOE CLEAN DEP"
- @$(RM) $(IOE_DEP)
-endif
-
-endif
diff --git a/can_mcp2515.h b/can_mcp2515.h
deleted file mode 100644
index 618051e..0000000
--- a/can_mcp2515.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <stdio.h>
-
-#include "spi.h"
-
-#ifndef _IOE_CAN_MCP2515_H_
-#define _IOE_CAN_MCP2515_H_
-#ifdef CONFIG_IOE_CAN_MCP2515
-
-void can_mcp2515_init(void);
-
-#endif /* CONFIG_IOE_CAN_MCP2515 */
-#endif /* _IOE_CAN_MCP2515_H_ */
diff --git a/src/can_mcp2515.c b/docs/add_support.md
index e69de29..e69de29 100644
--- a/src/can_mcp2515.c
+++ b/docs/add_support.md
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..4c261ff
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,10 @@
+AVR Input/Output expansion
+==========================
+
+Modules
+-------
+| Module | Header | Enable Config | Description |
+|-------------------------------|----------|-------------------------------------------|--------------------------------------------------------|
+| [IO Ports](modules/ioport.md) | ioport.h | CONFIG_IOPORTS and CONFIG_IOE_PCINTERRUPT | Simple input/output port access |
+| [SPI](modules/spi.md) | spi.h | CONFIG_SPI | Serial peripheral interface |
+| [USART](modules/usart.md) | usart.h | CONFIG_USART | Universal synchronous/asynchronous receive/transmitter |
diff --git a/docs/modules/ioport.md b/docs/modules/ioport.md
new file mode 100644
index 0000000..e777e0c
--- /dev/null
+++ b/docs/modules/ioport.md
@@ -0,0 +1,153 @@
+IO port
+=======
+To use include: `ioport.md`
+And define: `CONFIG_IOE_IOPORT`
+
+Defines simple access to io ports. This allows runtime access to any pin with just
+serialized identifier.
+
+Most of the functions has group and mask arguments. Group is letter, but in this
+library is represented as number and exact number is defined as macro definition.
+Mask is one shifted by index number(use \_BV macro). This way can be
+addressed all IO ports. Exact identification consult with datasheet. You can also
+use more than one index number and control more ports in single group with single
+command.
+
+WARNING: No check is implemented for right group number. Usage of unsupported
+value is undefined (write to other parts of memory can happen).
+
+## References
+### For output
+#### Function io_setout
+```C
+static inline void io_setout(uint8_t group, uint8_t mask)
+```
+Configures port of `group` with `mask` as output.
+Parameters:
+ group - Character specifying exact port group
+ mask - Binary shifted 1. Shift is equal to port index in specified group.
+
+#### Function io_hight
+```C
+static inline void io_hight(uint8_t group, uint8_t mask)
+```
+Sets output port to hight (also can be called as 1).
+WARNING: Invoke this only if io_setout is called before.
+Parameters:
+ group - Character specifying exact port group
+ mask - Binary shifted 1. Shift is equal to port index in specified group.
+
+#### Function io_low
+```C
+static inline void io_low(uint8_t group, uint8_t mask)
+```
+Sets output port to low (also called as 0).
+WARNING: Invoke this only if io_setout is called before.
+Parameters:
+ group - Number specifying exact port group
+ mask - Binary shifted 1. Shift is equal to port index in specified group.
+
+#### Function io_set
+```C
+static inline void io_set(uint8_t group, uint8_t mask, int8_t val)
+```
+Sets output port to value passed as argument.
+WARNING: Invoke this only if io_setout is called before.
+Parameters:
+ group - Number specifying exact port group
+ mask - Binary shifted 1. Shift is equal to port index in specified group.
+
+### For input
+#### Function io_setin
+```C
+static inline void io_setin(uint8_t group, uint8_t mask,
+ enum ioeIOInResistor resistor)
+```
+Configures port of `group` with `mask` as input with specified pull-up/down
+resistor.
+Parameters:
+ group - Number specifying exact port group
+ mask - Binary shifted 1. Shift is equal to port index in specified group.
+
+#### Function io_get
+```C
+static inline int8_t io_get(uint8_t group, uint8_t mask)
+```
+Returns current value of port. Note that you can use this also if port is
+configured as output.
+Parameters:
+ group - Number specifying exact port group
+ mask - Binary shifted 1. Shift is equal to port index in specified group.
+
+#### Enum ioeIOInResistor
+```C
+enum ioeIOInResistor {
+ IOE_IO_PULLUP,
+ IOE_IO_PULLDOWN
+};
+```
+This enum is used as argument for io_setin. Names should be self explanatory
+in this case.
+
+### Pin change interrupts
+#### Function io_change_sethook
+```C
+int8_t io_change_sethook(uint8_t group, uint8_t mask, uint8_t edge,
+ void (*change) (uint8_t group, uint8_t mask))
+```
+Registers function `change` as hook for pin change interrupt. `group` and `mask`
+specifies port and edge specifies on what edge should hook be called. `edge` can
+be IO_RISING or IO_FALLING or their binary combination with operator
+`|`.
+WARNING: `change` call is call during interrupt handling. You shouldn't be
+blocking execution for long time.
+Parameters:
+ group - Number specifying exact port group
+ mask - Binary shifted 1. Shift is equal to port index in specified group.
+ edge - Signals on what edge should be hook called.
+ change - Pointer to function used as interupt hook
+
+#### Function io_change_remhook
+```C
+int8_t io_change_remhook(void (*change) (uint8_t group, uint8_t mask))
+```
+Removes `change` hook.
+Parameters:
+ change - Pointer to function used as hook
+
+### Others
+#### Definitions IO_{GROUP}
+This defines exact numbers related to data-sheet groups. Always use these
+definition not direct numbers, you can ensure cross MCU support this way.
+
+#### Definitions IO_{GROUP}{INDEX}
+Because specifying group and mask as separate parameters is not always optimal,
+mcu support file should define all ports in form of single line definition in
+format `IOE_IO_{GROUP}{INDEX}`. Disadvantage is that with these definitions you
+can't use binary conjunction and so only one pin can be controlled with it.
+
+## Relevant examples
+* blink
+* pcinterrupt
+
+## Adding support
+For more information on how add support, see `doc/add_support.md`.
+Main definition is `MCUSUPPORT_IOPORT`. Define it to enable support.
+
+### IO_{GROUP}
+This should define any number that is handy for implementation of `IOE_IOE_PIN`,
+`IOE_IO_DDR` and `IOE_IO_PORT`.
+
+### IO_{PIN/DDR/PORT}
+These should calculate exact pointers to register `PORT{GROUP}` for PORT variant
+and likewise for others with group as argument. Common implementation would be
+like this:
+```C
+#define IOE_IO_PIN(GROUP) (* (volatile uint8_t *)(PINB + 0x3*GROUP))
+```
+### IO_{GROUP}{INDEX}
+This should be pair of group and one binary shifted to left relative to index.
+
+### MCUSUPPORT_PCINT{NUM}
+This defines that MCU supports specific pin change interrupt group. Also it
+defines value that is number of pins in group.
diff --git a/doc/spi.md b/docs/modules/spi.md
index 438d32d..3ae730c 100644
--- a/doc/spi.md
+++ b/docs/modules/spi.md
@@ -1,9 +1,9 @@
Serial peripheral interface
----------------------------
+===========================
This interface is link to MOSI and MISO pins. Also SS pin is used when slave mode initialized.
-## Functions
-### spi_init
+## References
+### spi\_init
```C
static inline void spi_init(enum spiMode mode)
```
@@ -11,22 +11,22 @@ Initializes SPI interface.
Parameters:
mode - Specify mode of SPI interface
-NOTE: Global interrupt must be enabled for right function of SPI.
+NOTE: Global interrupts must be enabled for right function of SPI.
-### spi_busy
+### spi\_busy
```C
static inline int8_t spi_busy(void)
```
Returns NULL when device is not busy.
When device is busy return values in non-zero.
-### spi_join
+### spi\_join
```C
static inline void spi_join(void)
```
Blocks processor until device is not busy.
-### spi_send
+### spi\_send
```C
static inline uint8_t spi_send(uint8_t data)
```
@@ -34,25 +34,25 @@ Swap bytes with slave over SPI.
This function blocks execution until device isn't busy (transfer completed).
WARNING: Invoke this only when interface is initialized in MASTER mode.
-### spi_transfer
+### spi\_transfer
```C
static inline void spi_transfer(uint8_t data)
```
Transfer byte to slave over SPI.
This function isn't blocking execution until transfer is complete.
-Always call spi_join before this function when called outside of spi_receive().
+Always call spi\_join before this function when called outside of spi\_receive().
WARNING: Invoke this only when interface is initialized in MASTER mode.
-### spi_expose
+### spi\_expose
```C
static inline void spi_expose(uint8_t data)
```
Expose data for next master request.
Please don't use this when device is busy.
-Best place to call this is spi_receive().
+Best place to call this is spi\_receive().
WARNING: Invoke this only when interface is initialized in SLAVE mode.
-## Function pointer spi_receive
+## Function pointer spi\_receive
```C
extern void (*spi_receive)(uint8_t data)
```
@@ -66,4 +66,4 @@ enum spiMode {
SPI_MODE_SLAVE
};
```
-This is used as parameter for spi_init function.
+This is used as parameter for spi\_init function.
diff --git a/docs/modules/tasks.md b/docs/modules/tasks.md
new file mode 100644
index 0000000..0078f00
--- /dev/null
+++ b/docs/modules/tasks.md
@@ -0,0 +1,37 @@
+Tasks
+=====
+Tasks allows separate jobs.
+
+## Functions
+### tasks_run
+```C
+int8_t tasks_run(void)
+```
+This function starts tasks execution. Should be called after all task slots are
+prepared and at least one task is started. This function exits if no task exist or
+all existing tasks exited.
+
+### task_init
+
+## Structures
+### Task
+```C
+typedef struct {
+ uint8_t flags;
+ void (*func) (void);
+} Task;
+```
+
+### TaskSlot
+```C
+typedef struct {
+ uint8_t flags;
+ Task *task;
+ uint8_t stack_size;
+ uint8_t stack[];
+} TaskSlot;
+```
+
+### Mutex
+
+### Semaphore
diff --git a/docs/modules/timer.md b/docs/modules/timer.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/modules/timer.md
diff --git a/docs/modules/usart.md b/docs/modules/usart.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/modules/usart.md
diff --git a/docs/modules/utils/buffer.md b/docs/modules/utils/buffer.md
new file mode 100644
index 0000000..4365c25
--- /dev/null
+++ b/docs/modules/utils/buffer.md
@@ -0,0 +1,105 @@
+buffer
+======
+In whole project are used ring buffers. This is so common that handling them is
+exported to separated header file. In fact it contains two implementations of
+buffers. One implementation is defined using preprocessor macros. Another one is
+plain C code.
+
+## Preprocessor implementation
+Preprocessor implementation is expected to be faster and less memory intense. Also
+more suitable for buffers of simple types (such us int). But this buffer has to be
+defined with known size at compile time and can't be resized. All this makes it
+good implementation for IO devices input and output buffers, but less for more
+complicated tasks containing for example sorting.
+
+### Macros
+#### IOEBUFFER
+```C
+IOEBUFFER(type, name, size)
+```
+This macro defines buffer. Use it to define new buffer.
+##### Parameters
+| type | Specify type of elements in buffer. Can be any valid C type |
+| name | Name of buffer. This is C variable name. |
+| size | Numerical value of buffer size |
+
+#### IOEBUFFER_INIT
+```C
+IOEBUFFER_INIT(name, size)
+```
+Use this to initialize buffer. Parameter `size` must be same as for IOEBUFFER
+(definition of buffer). You can use this also to reset buffer (remove all data
+from buffer).
+##### Parameters
+| name | Name if buffer. This is C variable name. |
+| size | Numerical value of buffer size |
+
+#### IOEBUFFER_PUT
+```C
+IOEBUFFER_PUT(name, size, data, mode)
+```
+Use this macro to add new data to buffer.
+##### Parameters
+| name | Name of buffer. This is C variable name. |
+| size | Numerical value of buffer size |
+| data | Data to be stored to buffer |
+| mode | This specifies action if buffer is full. |
+##### Modes
+| IOEBUFFER_MODE_BLOCK | Block execution until buffer has some free space. |
+| IOEBUFFER_MODE_OVERWRITE | Overwrites oldest added (fist to be read) |
+| IOEBUFFER_MODE_DROP | New data won't be stored to buffer if full |
+
+#### IOEBUFFER_GET
+```C
+IOEBUFFER_GET(name, size, variable)
+```
+Get value from buffer. Value is stored in `variable` (it is variable of same type
+as buffer data, not pointer to variable of same type). If no data is in buffer,
+variable is set to NULL.
+##### Parameters
+| name | Name of buffer. This is C variable name. |
+| size | Numerical value of buffer size. |
+| variable | Variable in which data will be stored in. |
+
+#### IOEBUFFER_CNT
+```C
+IOEBUFFER_CNT(name, size, variable)
+```
+Counts number of data entries in buffer and saves value to variable.
+##### Parameters
+| name | Name of buffer. This is C variable name. |
+| size | Numerical value of buffer size. |
+| variable | Int/Unsigned type variable where data count will be stored. |
+
+## C implementation
+C implementation is more general. Size is defined by calling initialization
+function. But it is using general pointers, so it is only able store pointers.
+
+As buffer identification is used defined type `IOEBuffer`. All functions takes
+pointer to this type as parameter. Because of this, it won't be described for
+every function.
+
+### Functions
+#### ioebuffer_init
+```C
+int8_t ioebuffer_init(IOEBuffer *buf, uint8_t size, uint8_t flags)
+```
+Initialized buffer and allocates required resources.
+##### Parameters
+| size | Number of elements to be maximally stored in buffer |
+| flags | TODO
+##### Flags
+TODO
+
+#### ioebuffer_uninit
+```C
+void ioebuffer_uninit(IOEBuffer *buf)
+```
+Frees all resources allocated during initialization of buffer. Use this every time
+you are freeing buffer.
+
+#### ioebuffer_put
+```C
+int8_t ioebuffer_put(IOEBuffer *buf, void *data)
+```
+Add `data` to buffer
diff --git a/docs/modules/utils/narray.md b/docs/modules/utils/narray.md
new file mode 100644
index 0000000..3e64f67
--- /dev/null
+++ b/docs/modules/utils/narray.md
@@ -0,0 +1,64 @@
+narray.h
+========
+This implements some helping functions for null terminated arrays. Null terminated
+arrays are used across whole project because they are simple and don't waste
+memory space. Their disadvantage is more complicated implementation of utility
+functions and much longer adding time (they are reallocated every time new data
+are added).
+
+This implementation is limited to only contains 255 elements(limited by uint8_t
+type). But it should be enough for basic usage. If you need store more than that,
+you should use different approach. Also only pointers can be stored.
+
+To define null terminated array just define pointer to you required pointer and set
+it to NULL. Such narray is handled as empty. Example:
+```C
+int **narray = 0;
+```
+After adding some data (in example case data of type `int*`) you can access them
+same as if you would working with simple array (`narray[i]`). Last element it such
+array is `NULL`. No more valid data are stored after `NULL` (This also means that
+`NULL` can't be stored to narray).
+
+All functions are taking as parameter `void ***array`, which is pointer to null
+terminated array. This parameter won't be described in functions.
+
+## Functions and macros
+### narray_add
+```C
+void narray_add(void ***array, void *data)
+```
+Add data to end of the array. This increases size of the array by one (two bytes).
+#### Parameters
+| data | data to be stored to array |
+
+### narray_remove
+```C
+void narray_remove(void ***array, void *data)
+```
+Remove specified data from array. This effectively decreases size of the array by
+one (two bytes).
+#### Parameters
+| data | data to be removed from array |
+
+### narray_size
+```C
+size_t narray_size(void ***array)
+```
+Returns size of array.
+
+### narray_free
+```C
+inline void narray_free(void ***array)
+```
+Frees whole array if allocated.
+
+### fornarray
+```C
+#define fornarray(array, i, data) for (i = 0; (data = array[i]) != 0; i++)
+```
+This is macro. It implements simple foreach cycle.
+#### Parameters
+| array | array it self (void ** not pointer) |
+| i | unsigned integer (uint8_t) |
+| data | variable which will be used to access data |
diff --git a/docs/usage.md b/docs/usage.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/usage.md
diff --git a/examples/blink/Makefile b/examples/blink/Makefile
new file mode 100644
index 0000000..43941b6
--- /dev/null
+++ b/examples/blink/Makefile
@@ -0,0 +1,64 @@
+MAKEFLAGS += --no-builtin-rules
+PROJNAME = blink
+
+SRC = blink.c
+
+OBJ = $(patsubst %.c,%.o,$(SRC)) # This creates list of *.o files from *.c
+
+.PHONY: all
+ifneq ("$(wildcard config)","") # Checking if configuration exists
+all: $(PROJNAME).hex
+ @echo Now you can flash $< to your chip.
+else
+all: help
+endif
+
+# Edit here help like you ever want
+.PHONY: help
+help:
+ @echo "AVR-IOE blink example"
+ @echo " all - Build example"
+ @echo " config - Start configuration program"
+ @echo " menuconfig - NCurses based configuration program"
+ @echo " help - Prints this text"
+ @echo " clean - Removing all object files generated from source files"
+
+.PHONY: clean
+clean:
+ @echo " CLEAN OBJ"
+ @$(RM) $(OBJ)
+ @echo " CLEAN $(PROJNAME).elf $(PROJNAME).hex"
+ @$(RM) $(PROJNAME).elf $(PROJNAME).hex
+ @$(MAKE) -C ../.. clean
+
+# Building targets are available only if configuration is generated
+ifneq ("$(wildcard config)","")
+-include config
+# If you want change some standard CFLAGS, change them in configuration not here.
+# Add here only options that should not be applied to avr-ioe also.
+CFLAGS = -I../../include -mmcu=$(MMCU) -imacros ../../.config.h \
+ $(shell echo $(CONFCFLAGS)) $(shell echo -DF_CPU=$(F_CPU)000L)
+
+$(PROJNAME).elf: ../../libioe.a
+$(PROJNAME).elf: $(OBJ)
+ @echo " LD $@"
+ @avr-gcc -Os -mmcu=$(MMCU) $^ -o $@ -L../.. -lioe
+
+$(PROJNAME).hex: $(PROJNAME).elf
+ @echo " OBJCOPY $@"
+ @avr-objcopy -O ihex -R .eeprom $< $@
+
+$(OBJ): %.o: %.c ../../libioe.a
+ @echo " CC $@"
+ @avr-gcc $(CFLAGS) -c -o $@ $<
+
+../../libioe.a: config
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. libioe.a
+endif
+
+config:
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. config
+
+.PHONY: menuconfig
+menuconfig:
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. menuconfig
diff --git a/examples/blink/README.md b/examples/blink/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/blink/README.md
diff --git a/examples/blink/blink.c b/examples/blink/blink.c
new file mode 100644
index 0000000..8386d4b
--- /dev/null
+++ b/examples/blink/blink.c
@@ -0,0 +1,14 @@
+#include <avr/io.h>
+#include <util/delay.h>
+#include <ioport.h>
+
+int main() {
+ io_setout(IO_B3);
+
+ while (1) {
+ io_hight(IO_B3);
+ _delay_ms(500);
+ io_low(IO_B3);
+ _delay_ms(500);
+ }
+}
diff --git a/examples/blink/config b/examples/blink/config
new file mode 100644
index 0000000..09169d4
--- /dev/null
+++ b/examples/blink/config
@@ -0,0 +1,24 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# AVR-IOE configuration
+#
+MMCU=atmega328p
+ATMEGA328P=y
+# ATTINY85 is not set
+F_CPU=16000
+
+#
+# Compilation options
+#
+GNUTOOLCHAIN_PREFIX=avr-
+CONFCFLAGS=-Os -ffunction-sections -fdata-sections -fshort-enums -Wall
+MCUSUPPORT_IOPORTS=y
+CONFIG_IOPORTS=y
+MCUSUPPORT_PCINT0=y
+MCUSUPPORT_PCINT1=y
+MCUSUPPORT_PCINT2=y
+# CONFIG_IOPORTS_PCINT is not set
+MCUSUPPORT_SPI=y
+# CONFIG_SPI is not set
+MCUSUPPORT_USART=y
+# CONFIG_USART is not set
diff --git a/examples/blink/config.orig b/examples/blink/config.orig
new file mode 100644
index 0000000..529a7d3
--- /dev/null
+++ b/examples/blink/config.orig
@@ -0,0 +1,24 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# AVR-IOE configuration
+#
+MMCU="atmega328p"
+ATMEGA328P=y
+# ATTINY85 is not set
+F_CPU=16000
+
+#
+# Compilation options
+#
+GNUTOOLCHAIN_PREFIX="avr-"
+CONFCFLAGS="-Os -ffunction-sections -fdata-sections -fshort-enums -Wall"
+MCUSUPPORT_IOPORTS=y
+CONFIG_IOPORTS=y
+MCUSUPPORT_PCINT0=y
+MCUSUPPORT_PCINT1=y
+MCUSUPPORT_PCINT2=y
+# CONFIG_IOPORTS_PCINT is not set
+MCUSUPPORT_SPI=y
+# CONFIG_SPI is not set
+MCUSUPPORT_USART=y
+# CONFIG_USART is not set
diff --git a/examples/spiblink/Makefile b/examples/spiblink/Makefile
new file mode 100644
index 0000000..621f237
--- /dev/null
+++ b/examples/spiblink/Makefile
@@ -0,0 +1,66 @@
+MAKEFLAGS += --no-builtin-rules
+PROJNAME = spiblink
+
+MSRC = master.c
+SSRC = slave.c
+
+MOBJ = $(patsubst %.c,%.o,$(MSRC))
+SOBJ = $(patsubst %.c,%.o,$(SSRC))
+
+.PHONY: all
+ifneq ("$(wildcard config)","") # Checking if configuration exists
+all: master.hex slave.hex
+ @echo Now you can flash $^ to your chips.
+else
+all: help
+endif
+
+# Edit here help like you ever want
+.PHONY: help
+help:
+ @echo "AVR-IOE USART echo example"
+ @echo " all - Build example"
+ @echo " config - Start configuration program"
+ @echo " menuconfig - NCurses based configuration program"
+ @echo " help - Prints this text"
+ @echo " clean - Removing all object files generated from source files"
+
+.PHONY: clean
+clean:
+ @echo " CLEAN OBJ"
+ @$(RM) $(MOBJ) $(SOBJ)
+ @echo " CLEAN master and slave *.hex, *.elf"
+ @$(RM) master.elf master.hex
+ @$(RM) slave.elf slave.hex
+ @$(MAKE) -C ../.. clean
+
+# Building targets are available only if configuration is generated
+ifneq ("$(wildcard config)","")
+-include config
+# If you want change some standard CFLAGS, change them in configuration not here.
+# Add here only options that should not be applied to avr-ioe also.
+CFLAGS = -I../../include -mmcu=$(MMCU) -imacros ../../.config.h \
+ $(shell echo $(CONFCFLAGS)) $(shell echo -DF_CPU=$(F_CPU)000L)
+
+master.elf slave.elf: %.elf: ../../libioe.a %.o
+ @echo " LD $@"
+ @avr-gcc -Os -mmcu=$(MMCU) $^ -o $@ -L../.. -lioe
+
+master.hex slave.hex: %.hex: %.elf
+ @echo " OBJCOPY $@"
+ @avr-objcopy -O ihex -R .eeprom $< $@
+
+$(MOBJ) $(SOBJ): %.o: %.c ../../libioe.a
+ @echo " CC $@"
+ @avr-gcc $(CFLAGS) -c -o $@ $<
+
+../../libioe.a: config
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. libioe.a
+endif
+
+config:
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. config
+
+.PHONY: menuconfig
+menuconfig:
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. menuconfig
diff --git a/examples/spiblink/config b/examples/spiblink/config
new file mode 100644
index 0000000..7455947
--- /dev/null
+++ b/examples/spiblink/config
@@ -0,0 +1,23 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# AVR-IOE configuration
+#
+MMCU=atmega328p
+ATMEGA328P=y
+# ATTINY85 is not set
+F_CPU=16000
+
+#
+# Compilation options
+#
+GNUTOOLCHAIN_PREFIX=avr-
+CONFCFLAGS=-Os -ffunction-sections -fdata-sections -fshort-enums -Wall
+MCUSUPPORT_IOPORTS=y
+# CONFIG_IOPORTS is not set
+MCUSUPPORT_PCINT0=y
+MCUSUPPORT_PCINT1=y
+MCUSUPPORT_PCINT2=y
+MCUSUPPORT_SPI=y
+CONFIG_SPI=y
+MCUSUPPORT_USART=y
+# CONFIG_USART is not set
diff --git a/examples/spiblink/config.orig b/examples/spiblink/config.orig
new file mode 100644
index 0000000..af7b0a5
--- /dev/null
+++ b/examples/spiblink/config.orig
@@ -0,0 +1,23 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# AVR-IOE configuration
+#
+MMCU="atmega328p"
+ATMEGA328P=y
+# ATTINY85 is not set
+F_CPU=16000
+
+#
+# Compilation options
+#
+GNUTOOLCHAIN_PREFIX="avr-"
+CONFCFLAGS="-Os -ffunction-sections -fdata-sections -fshort-enums -Wall"
+MCUSUPPORT_IOPORTS=y
+# CONFIG_IOPORTS is not set
+MCUSUPPORT_PCINT0=y
+MCUSUPPORT_PCINT1=y
+MCUSUPPORT_PCINT2=y
+MCUSUPPORT_SPI=y
+CONFIG_SPI=y
+MCUSUPPORT_USART=y
+# CONFIG_USART is not set
diff --git a/examples/spiblink/makefile b/examples/spiblink/makefile
deleted file mode 100644
index 60ba9c9..0000000
--- a/examples/spiblink/makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-MAKEFLAGS += --no-builtin-rules
-
-MMCU = atmega328p
-F_CPU = 16000000L
-IOE_PREFIX = ../..
-IOE_CFLAGS ?= -Os -ffunction-sections -fdata-sections -fshort-enums -g -Wall \
- -DF_CPU=$(F_CPU) -mmcu=$(MMCU) \
- -DCONFIG_IOE_SPI
-
-.PHONY: all
-all: master.hex slave.hex
- @echo
- @echo Flash master.hex and slave.hex to two chips and... TODO
-
-.PHONY: all
-clean: ioeclean
- $(RM) master.o slave.o
- $(RM) master.elf master.hex
- $(RM) slave.elf slave.hex
-
-include ../../avr-ioe.mk
-
-master.elf: master.o
-slave.elf: slave.o
-master.elf slave.elf: %.elf: $(IOE_OBJ_SPI)
- avr-gcc -Os -mmcu=$(MMCU) $^ -o $@
-
-master.hex slave.hex: %.hex: %.elf
- avr-objcopy -O ihex -R .eeprom $< $@
-
-master.o slave.o: %.o: %.c
- avr-gcc $(IOE_CFLAGS) -c -o $@ $<
diff --git a/examples/spiblink/master.c b/examples/spiblink/master.c
index 267d7b2..1cc4289 100644
--- a/examples/spiblink/master.c
+++ b/examples/spiblink/master.c
@@ -1,6 +1,6 @@
#include <avr/io.h>
#include <util/delay.h>
-#include "../../spi.h"
+#include <spi.h>
int main() {
DDRB |= _BV(DDB1) | _BV(DDB2);
diff --git a/examples/spiblink/slave.c b/examples/spiblink/slave.c
index cf14408..91a8237 100644
--- a/examples/spiblink/slave.c
+++ b/examples/spiblink/slave.c
@@ -1,6 +1,6 @@
#include <avr/io.h>
#include <util/delay.h>
-#include "../../spi.h"
+#include <spi.h>
void receive(uint8_t data);
diff --git a/examples/usartecho/Makefile b/examples/usartecho/Makefile
new file mode 100644
index 0000000..900fe09
--- /dev/null
+++ b/examples/usartecho/Makefile
@@ -0,0 +1,64 @@
+MAKEFLAGS += --no-builtin-rules
+PROJNAME = usartecho
+
+SRC = echo.c
+
+OBJ = $(patsubst %.c,%.o,$(SRC)) # This creates list of *.o files from *.c
+
+.PHONY: all
+ifneq ("$(wildcard config)","") # Checking if configuration exists
+all: $(PROJNAME).hex
+ @echo Now you can flash $< to your chip.
+else
+all: help
+endif
+
+# Edit here help like you ever want
+.PHONY: help
+help:
+ @echo "AVR-IOE USART echo example"
+ @echo " all - Build example"
+ @echo " config - Start configuration program"
+ @echo " menuconfig - NCurses based configuration program"
+ @echo " help - Prints this text"
+ @echo " clean - Removing all object files generated from source files"
+
+.PHONY: clean
+clean:
+ @echo " CLEAN OBJ"
+ @$(RM) $(OBJ)
+ @echo " CLEAN $(PROJNAME).elf $(PROJNAME).hex"
+ @$(RM) $(PROJNAME).elf $(PROJNAME).hex
+ @$(MAKE) -C ../.. clean
+
+# Building targets are available only if configuration is generated
+ifneq ("$(wildcard config)","")
+-include config
+# If you want change some standard CFLAGS, change them in configuration not here.
+# Add here only options that should not be applied to avr-ioe also.
+CFLAGS = -I../../include -mmcu=$(MMCU) -imacros ../../.config.h \
+ $(shell echo $(CONFCFLAGS)) $(shell echo -DF_CPU=$(F_CPU)000L)
+
+$(PROJNAME).elf: ../../libioe.a
+$(PROJNAME).elf: $(OBJ)
+ @echo " LD $@"
+ @avr-gcc -Os -mmcu=$(MMCU) $^ -o $@ -L../.. -lioe
+
+$(PROJNAME).hex: $(PROJNAME).elf
+ @echo " OBJCOPY $@"
+ @avr-objcopy -O ihex -R .eeprom $< $@
+
+$(OBJ): %.o: %.c ../../libioe.a
+ @echo " CC $@"
+ @avr-gcc $(CFLAGS) -c -o $@ $<
+
+../../libioe.a: config
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. libioe.a
+endif
+
+config:
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. config
+
+.PHONY: menuconfig
+menuconfig:
+ @CONFIG=$$(readlink -f config) $(MAKE) -C ../.. menuconfig
diff --git a/examples/usartecho/config b/examples/usartecho/config
new file mode 100644
index 0000000..052a5c4
--- /dev/null
+++ b/examples/usartecho/config
@@ -0,0 +1,41 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# AVR-IOE configuration
+#
+MMCU=atmega328p
+ATMEGA328P=y
+# ATTINY85 is not set
+F_CPU=16000
+
+#
+# Compilation options
+#
+GNUTOOLCHAIN_PREFIX=avr-
+CONFCFLAGS=-Os -ffunction-sections -fdata-sections -fshort-enums -Wall
+MCUSUPPORT_IOPORTS=y
+# CONFIG_IOPORTS is not set
+MCUSUPPORT_PCINT0=y
+MCUSUPPORT_PCINT1=y
+MCUSUPPORT_PCINT2=y
+MCUSUPPORT_SPI=y
+# CONFIG_SPI is not set
+MCUSUPPORT_USART=y
+CONFIG_USART=y
+CONFIG_USART_BAUD=115200
+USART_PARITY_C_NONE=y
+# USART_PARITY_C_ODD is not set
+# USART_PARITY_C_EVEN is not set
+CONFIG_USART_PARITY=USART_PARITY_NONE
+CONFIG_USART_DATABITS=8
+USART_STOPBIT_C_SINGLE=y
+# USART_STOPBIT_C_DOUBLE is not set
+CONFIG_USART_STOPBIT=USART_STOPBIT_SINGLE
+CONFIG_USART_OUTPUT_BUFFER=y
+CONFIG_USART_OUTBUFFER_SIZE=64
+USART_OUTBUFFER_MODE_C_BLOCK=y
+# USART_OUTBUFFER_MODE_C_OVERWRITE is not set
+# USART_OUTBUFFER_MODE_C_DROP is not set
+CONFIG_USART_OUTBUFFER_MODE=0
+# CONFIG_USART_INPUT_BUFFER is not set
+CONFIG_USART_INBUFFER_SIZE=32
+CONFIG_USART_INBUFFER_MODE=0
diff --git a/examples/usartecho/config.orig b/examples/usartecho/config.orig
new file mode 100644
index 0000000..8bc1db9
--- /dev/null
+++ b/examples/usartecho/config.orig
@@ -0,0 +1,41 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# AVR-IOE configuration
+#
+MMCU="atmega328p"
+ATMEGA328P=y
+# ATTINY85 is not set
+F_CPU=16000
+
+#
+# Compilation options
+#
+GNUTOOLCHAIN_PREFIX="avr-"
+CONFCFLAGS="-Os -ffunction-sections -fdata-sections -fshort-enums -Wall"
+MCUSUPPORT_IOPORTS=y
+# CONFIG_IOPORTS is not set
+MCUSUPPORT_PCINT0=y
+MCUSUPPORT_PCINT1=y
+MCUSUPPORT_PCINT2=y
+MCUSUPPORT_SPI=y
+# CONFIG_SPI is not set
+MCUSUPPORT_USART=y
+CONFIG_USART=y
+CONFIG_USART_BAUD=115200
+USART_PARITY_C_NONE=y
+# USART_PARITY_C_ODD is not set
+# USART_PARITY_C_EVEN is not set
+CONFIG_USART_PARITY="USART_PARITY_NONE"
+CONFIG_USART_DATABITS=8
+USART_STOPBIT_C_SINGLE=y
+# USART_STOPBIT_C_DOUBLE is not set
+CONFIG_USART_STOPBIT="USART_STOPBIT_SINGLE"
+CONFIG_USART_OUTPUT_BUFFER=y
+CONFIG_USART_OUTBUFFER_SIZE=64
+USART_OUTBUFFER_MODE_C_BLOCK=y
+# USART_OUTBUFFER_MODE_C_OVERWRITE is not set
+# USART_OUTBUFFER_MODE_C_DROP is not set
+CONFIG_USART_OUTBUFFER_MODE=0
+# CONFIG_USART_INPUT_BUFFER is not set
+CONFIG_USART_INBUFFER_SIZE=32
+CONFIG_USART_INBUFFER_MODE=0
diff --git a/examples/usartecho/echo.c b/examples/usartecho/echo.c
index 12b88f6..d685750 100644
--- a/examples/usartecho/echo.c
+++ b/examples/usartecho/echo.c
@@ -1,7 +1,7 @@
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
-#include "../../usart.h"
+#include <usart.h>
void rec(uint8_t data) {
if (data == '\r') {
diff --git a/examples/usartecho/makefile b/examples/usartecho/makefile
deleted file mode 100644
index 15254c6..0000000
--- a/examples/usartecho/makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-MAKEFLAGS += --no-builtin-rules
-
-MMCU = atmega328p
-F_CPU = 16000000L
-IOE_PREFIX = ../..
-IOE_SHORTOUTPUT=y
-IOE_CFLAGS = -Os -fshort-enums -Wall \
- -DF_CPU=$(F_CPU) -mmcu=$(MMCU) \
- -DCONFIG_IOE_USART \
- -DCONFIG_IOE_USART_OUTBUFFER_SIZE=64 \
- -DCONFIG_IOE_USART_OUTBUFFER_MODE=0 \
- -DCONFIG_IOE_USART_BAUD=115200 \
- -DCONFIG_IOE_USART_PARITY=USART_PARITY_NONE \
- -DCONFIG_IOE_USART_STOPBIT=USART_STOPBIT_SINGLE \
- -DCONFIG_IOE_USART_DATABITS=8
-
-all: usart.hex
- @echo Now you can flash usart.hex to your chip.
-
-clean: ioeclean
- $(RM) echo.o
- $(RM) usart.elf usart.hex
-
-include ../../avr-ioe.mk
-
-usart.elf: %.elf: $(IOE_OBJ) echo.o
- @echo " LD $@"
- @avr-gcc -Os -mmcu=$(MMCU) $^ -o $@
-
-usart.hex: %.hex: %.elf
- @echo " OBJCOPY $@"
- @avr-objcopy -O ihex -R .eeprom $< $@
-
-echo.o: %.o: %.c
- @echo " CC $@"
- @avr-gcc $(IOE_CFLAGS) -c -o $@ $<
diff --git a/include/adc.h b/include/adc.h
new file mode 100644
index 0000000..86429a1
--- /dev/null
+++ b/include/adc.h
@@ -0,0 +1,15 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <stdint.h>
+
+#ifndef _IOE_ADC_H_
+#define _IOE_ADC_H_
+#ifdef CONFIG_IOE_ADC
+#ifndef MCUSUPPORT_ADC
+#error "No ADC support for your mcu. Probably just not implemented yet."
+#endif
+
+int8_t ioe_adc(uint8_t input);
+
+#endif /* CONFIG_IOE_ADC */
+#endif /* _IOE_ADC_H_ */
diff --git a/avr-ioe.h b/include/avr-ioe.h
index ac58ee7..cb84ad9 100644
--- a/avr-ioe.h
+++ b/include/avr-ioe.h
@@ -1,3 +1,2 @@
-#include "buffers.h"
#include "spi.h"
#include "usart.h"
diff --git a/include/can/global.h b/include/can/global.h
new file mode 100644
index 0000000..5d88fe6
--- /dev/null
+++ b/include/can/global.h
@@ -0,0 +1,20 @@
+#include <stdint.h>
+
+#ifndef _IOE_CAN_GLOBAL_
+#define _IOE_CAN_GLOBAL_
+
+typedef struct {
+ uint16_t id;
+ uint8_t length;
+ uint8_t data[8];
+} CanFrame;
+
+typedef struct {
+ CanFrame **buffer;
+ void *udata;
+} Can;
+
+
+void can_send(Can *can, CanFrame *frame);
+
+#endif /* _IOE_CAN_GLOBAL_ */
diff --git a/include/can/mcp2515.h b/include/can/mcp2515.h
new file mode 100644
index 0000000..59376f7
--- /dev/null
+++ b/include/can/mcp2515.h
@@ -0,0 +1,36 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <stdint.h>
+
+#include "spi.h"
+#include "global.h"
+
+#ifndef _IOE_CAN_MCP2515_H_
+#define _IOE_CAN_MCP2515_H_
+#ifdef CONFIG_IOE_CAN_MCP2515
+#ifndef CONFIG_IOE_SPI
+#error "Please define CONFIG_IOE_SPI. MCP2515 requires SPI."
+#endif
+
+// TODO registers
+#define CAN_MCP2515_CANCTL
+// TODO buffers
+
+typedef struct {
+ uint8_t group, mask;
+} CanMcp2515;
+
+int8_t can_mcp2515_init(CanMcp2515 * can, uint8_t group, uint8_t mask);
+
+void can_mcp2515_reset(CanMcp2515 * can);
+uint8_t can_mcp2515_read(CanMcp2515 * can, uint8_t address);
+uint8_t can_mcp2515_readrx(CanMcp2515 * can, uint8_t buffer);
+void can_mcp2515_write(CanMcp2515 * can, uint8_t address, uint8_t data);
+void can_mcp2515_loadrx(CanMcp2515 * can, uint8_t buffer, uint8_t data);
+uint8_t can_mcp2515_rdstat(CanMcp2515 * can);
+uint8_t can_mcp2515_rxstat(CanMcp2515 * can);
+void can_mcp2515_bitmod(CanMcp2515 * can, uint8_t address, uint8_t mask,
+ uint8_t data);
+
+#endif /* CONFIG_IOE_CAN_MCP2515 */
+#endif /* _IOE_CAN_MCP2515_H_ */
diff --git a/include/can/software.h b/include/can/software.h
new file mode 100644
index 0000000..b443e42
--- /dev/null
+++ b/include/can/software.h
@@ -0,0 +1,9 @@
+#include <avr/io.h>
+#include <util/delay.h>
+#include <stdint.h>
+
+#ifndef _IOE_CAN_SOFTWARE_H_
+#define _IOE_CAN_SOFTWARE_H_
+
+
+#endif /* _IOE_CAN_SOFTWARE_H_ */
diff --git a/include/ioport.h b/include/ioport.h
new file mode 100644
index 0000000..1022493
--- /dev/null
+++ b/include/ioport.h
@@ -0,0 +1,55 @@
+#include <stdlib.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#include "mcu/mcu_def.h"
+
+#ifndef _IOE_IOPORT_H_
+#define _IOE_IOPORT_H_
+#ifdef CONFIG_IOPORTS
+
+enum ioInResistor {
+ IO_PULLUP,
+ IO_PULLDOWN
+};
+
+static inline void io_setout(uint8_t group, uint8_t mask) {
+ IO_DDR(group) |= mask;
+}
+static inline void io_hight(uint8_t group, uint8_t mask) {
+ IO_PORT(group) |= mask;
+}
+static inline void io_low(uint8_t group, uint8_t mask) {
+ IO_PORT(group) &= ~mask;
+}
+static inline void io_set(uint8_t group, uint8_t mask, int8_t val) {
+ if (val)
+ io_hight(group, mask);
+ else
+ io_low(group, mask);
+}
+
+static inline void io_setin(uint8_t group, uint8_t mask,
+ enum ioInResistor resistor) {
+ IO_DDR(group) &= ~mask;
+ if (resistor == IO_PULLUP)
+ IO_PORT(group) |= mask;
+ else
+ IO_PORT(group) &= ~mask;
+}
+static inline int8_t io_get(uint8_t group, uint8_t mask) {
+ return (int8_t) IO_PIN(group) & mask;
+}
+
+#ifdef CONFIG_PCINT
+
+#define IO_RISING (1 << 0)
+#define IO_FALLING (1 << 1)
+void io_change_sethook(uint8_t group, uint8_t mask, uint8_t edge,
+ void (*change) (uint8_t group, uint8_t mask));
+void io_change_remhook(void (*change) (uint8_t group, uint8_t mask));
+void io_change_clearhooks(void);
+
+#endif /* CONFIG_PCINT */
+#endif /* CONFIG_IOPORTS */
+#endif /* _IOE_IOPORT_H_ */
diff --git a/include/mcu/Kconfig b/include/mcu/Kconfig
new file mode 100644
index 0000000..a69903f
--- /dev/null
+++ b/include/mcu/Kconfig
@@ -0,0 +1,11 @@
+config MMCU
+ string
+ default "atmega328p" if ATMEGA328P
+
+choice MCU
+ prompt "Microcontroller (MMCU)"
+
+source include/mcu/atmega328p.Kconfig
+source include/mcu/attiny85.Kconfig
+
+endchoice
diff --git a/include/mcu/atmega328p.Kconfig b/include/mcu/atmega328p.Kconfig
new file mode 100644
index 0000000..5b4bf27
--- /dev/null
+++ b/include/mcu/atmega328p.Kconfig
@@ -0,0 +1,8 @@
+config ATMEGA328P
+ bool "atmega328p"
+ select MCUSUPPORT_IOPORTS
+ select MCUSUPPORT_PCINT0
+ select MCUSUPPORT_PCINT1
+ select MCUSUPPORT_PCINT2
+ select MCUSUPPORT_SPI
+ select MCUSUPPORT_USART
diff --git a/include/mcu/atmega328p.h b/include/mcu/atmega328p.h
new file mode 100644
index 0000000..994e9e6
--- /dev/null
+++ b/include/mcu/atmega328p.h
@@ -0,0 +1,63 @@
+/* This is specific configuration for ATmega328P.
+ * Also applies on ATmega48A, ATmega48PA, ATmega88A, ATmega88PA, ATmega168A and
+ * ATmega168PA.
+ */
+#include <avr/io.h>
+
+// IO Ports
+#define MCUSUPPORT_IOPORTS
+#define IO_B 0
+#define IO_C 1
+#define IO_D 2
+#define IO_PIN(GROUP) (* (volatile uint8_t *)(PINB + 0x3*GROUP))
+#define IO_DDR(GROUP) (* (volatile uint8_t *)(DDRB + 0x3*GROUP))
+#define IO_PORT(GROUP) (* (volatile uint8_t *)(PORTB + 0x3*GROUP))
+#define IO_B0 IO_B, (1 << 0)
+#define IO_B1 IO_B, (1 << 1)
+#define IO_B2 IO_B, (1 << 2)
+#define IO_B3 IO_B, (1 << 3)
+#define IO_B4 IO_B, (1 << 4)
+#define IO_B5 IO_B, (1 << 5)
+#define IO_B6 IO_B, (1 << 6)
+#define IO_B7 IO_B, (1 << 7)
+#define IO_C0 IO_C, (1 << 0)
+#define IO_C1 IO_C, (1 << 1)
+#define IO_C2 IO_C, (1 << 2)
+#define IO_C3 IO_C, (1 << 3)
+#define IO_C4 IO_C, (1 << 4)
+#define IO_C5 IO_C, (1 << 5)
+#define IO_C6 IO_C, (1 << 6)
+#define IO_D0 IO_D, (1 << 0)
+#define IO_D1 IO_D, (1 << 1)
+#define IO_D2 IO_D, (1 << 2)
+#define IO_D3 IO_D, (1 << 3)
+#define IO_D4 IO_D, (1 << 4)
+#define IO_D5 IO_D, (1 << 5)
+#define IO_D6 IO_D, (1 << 6)
+#define IO_D7 IO_D, (1 << 7)
+#define MCUSUPPORT_PCINT0 8
+#define MCUSUPPORT_PCINT1 8
+#define MCUSUPPORT_PCINT2 8
+// SPI
+#define MCUSUPPORT_SPI
+#define DDR_SPI DDRB
+#define DD_SS DDB2
+#define DD_MOSI DDB3
+#define DD_MISO DDB4
+#define DD_SCLK DDB5
+#define PORT_SPI PORTB
+#define PORT_SS PORTB2
+#define PORT_MOSI PORTB3
+#define PORT_MISO PORTB4
+#define PORT_SCLK PORTB5
+// USART
+#define MCUSUPPORT_USART
+// TWI
+#define MCUSUPPORT_TWI
+// TIMERS
+#define MCUSUPPORT_TIMER_0
+#define MCUSUPPORT_TIMER_1
+#define MCUSUPPORT_TIMER_2
+#define COUNTER0_PWM 0
+#define COUNTER1_16PWM 1
+#define COUNTER2_PWM_ASYNC 2
diff --git a/mcu/ATmega32U4.h b/include/mcu/atmega32u4.h
index 16351e8..16351e8 100644
--- a/mcu/ATmega32U4.h
+++ b/include/mcu/atmega32u4.h
diff --git a/mcu/ATmega8A.h b/include/mcu/atmega8a.h
index a2d3adf..a2d3adf 100644
--- a/mcu/ATmega8A.h
+++ b/include/mcu/atmega8a.h
diff --git a/include/mcu/attiny4313.h b/include/mcu/attiny4313.h
new file mode 100644
index 0000000..3a2d0b9
--- /dev/null
+++ b/include/mcu/attiny4313.h
@@ -0,0 +1,46 @@
+/* This is specific configuration for ATtiny4313.
+ * This configuration also applies on ATtiny2313A.
+ */
+#include <avr/io.h>
+
+// IO Ports
+#define MCUSUPPORT_IOPORTS
+#define IO_A 0
+#define IO_B 1
+#define IO_D 3
+#define IO_PIN(GROUP) (* (volatile uint8_t *)(PINB + 0x3*GROUP))
+#define IO_DDR(GROUP) (* (volatile uint8_t *)(DDRB + 0x3*GROUP))
+#define IO_PORT(GROUP) (* (volatile uint8_t *)(PORTB + 0x3*GROUP))
+#define IO_A0 IO_A, (1 << 0)
+#define IO_A1 IO_A, (1 << 1)
+#define IO_A2 IO_A, (1 << 2)
+#define IO_B0 IO_B, (1 << 0)
+#define IO_B1 IO_B, (1 << 1)
+#define IO_B2 IO_B, (1 << 2)
+#define IO_B3 IO_B, (1 << 3)
+#define IO_B4 IO_B, (1 << 4)
+#define IO_B5 IO_B, (1 << 5)
+#define IO_B6 IO_B, (1 << 6)
+#define IO_B7 IO_B, (1 << 7)
+#define IO_D0 IO_D, (1 << 0)
+#define IO_D1 IO_D, (1 << 1)
+#define IO_D2 IO_D, (1 << 2)
+#define IO_D3 IO_D, (1 << 3)
+#define IO_D4 IO_D, (1 << 4)
+#define IO_D5 IO_D, (1 << 5)
+#define IO_D6 IO_D, (1 << 6)
+#define MCUSUPPORT_PCINT0 8 // TODO this is B
+#define MCUSUPPORT_PCINT1 7 // But this is D
+#define MCUSUPPORT_PCINT2 3 // And this is A, this is not expected in ioport.c
+// SPI USI
+#define MCUSUPPORT_USI
+#define DDR_USI DDRB
+#define DD_DI DDB5
+#define DD_DO DDB6
+#define DD_USCK DDB7
+#define PORT_USI PORTB
+#define PORT_DI PORTB5
+#define PORT_DO PORTB6
+#define PORT_USCK PORTB7
+// USART
+#define MCUSUPPORT_USART0
diff --git a/include/mcu/attiny85.Kconfig b/include/mcu/attiny85.Kconfig
new file mode 100644
index 0000000..d58c1d8
--- /dev/null
+++ b/include/mcu/attiny85.Kconfig
@@ -0,0 +1,4 @@
+config ATTINY85
+ bool "attiny85"
+ select MCUSUPPORT_IOPORTS
+ select MCUSUPPORT_PCINT0
diff --git a/mcu/ATtiny85.h b/include/mcu/attiny85.h
index 19db90d..c342bbb 100644
--- a/mcu/ATtiny85.h
+++ b/include/mcu/attiny85.h
@@ -3,6 +3,19 @@
*/
#include <avr/io.h>
+// IO Ports
+#define MCUSUPPORT_IOPORTS
+#define IO_B 0
+#define IO_PIN(GROUP) PINB
+#define IO_DDR(GROUP) DDRB
+#define IO_PORT(GROUP) PORTB
+#define IO_B0 IO_B, (1 << 0)
+#define IO_B1 IO_B, (1 << 1)
+#define IO_B2 IO_B, (1 << 2)
+#define IO_B3 IO_B, (1 << 3)
+#define IO_B4 IO_B, (1 << 4)
+#define IO_B5 IO_B, (1 << 5)
+#define MCUSUPPORT_PCINT0 6
// SPI USI
#define MCUSUPPORT_USI
#define DDR_USI DDRB
diff --git a/mcu/mcu.h b/include/mcu/mcu.h
index e1272b9..e1272b9 100644
--- a/mcu/mcu.h
+++ b/include/mcu/mcu.h
diff --git a/mcu/mcu_def.h b/include/mcu/mcu_def.h
index 51b70fe..472b607 100644
--- a/mcu/mcu_def.h
+++ b/include/mcu/mcu_def.h
@@ -1,21 +1,21 @@
#include "mcu.h"
#if __MCU_ATmega328p__
-#include "ATmega328P.h"
+#include "atmega328p.h"
#endif
#if __MCU_ATmega32U4__
-#include "ATmega32U4.h"
+#include "atmega32u4.h"
#endif
#if __MCU_ATmega8A__
-#include "ATmega8A.h"
+#include "atmega8a.h"
#endif
#if __MCU_ATtiny4313__
-#include "ATtiny4313.h"
+#include "attiny4313.h"
#endif
#if __MCU_ATtiny85__
-#include "ATtiny85.h"
+#include "attiny85.h"
#endif
diff --git a/pwm.h b/include/pwm.h
index 0dbc007..0dbc007 100644
--- a/pwm.h
+++ b/include/pwm.h
diff --git a/sensor_dht22.h b/include/sensors/dht22.h
index 6ddcf9c..aabb442 100644
--- a/sensor_dht22.h
+++ b/include/sensors/dht22.h
@@ -2,11 +2,12 @@
#include <util/delay.h>
#include <stdint.h>
-#include "tasks.h"
-#include "timer.h"
+#include "../tasks.h"
+#include "../timer.h"
#ifndef _IOE_SENSOR_DHT22_H_
#define _IOE_SENSOR_DHT22_H_
+#ifdef CONFIG_IOE_SENSOR_DHT22
struct dht22_value {
uint8_t integral;
@@ -28,6 +29,7 @@ extern const struct dht22_port dht22_ports[];
* Initialize port for sensor
*/
void dht22_init(uint8_t port);
+
/*
* Read values from dht22
* rh - relative
@@ -36,4 +38,5 @@ void dht22_init(uint8_t port);
int8_t dht22_read(uint8_t portindex, struct dht22_value *rh,
struct dht22_value *t);
+#endif /* CONFIG_IOE_SENSOR_DHT22 */
#endif /* _IOE_SENSOR_DHT22_H_ */
diff --git a/spi.h b/include/spi.h
index 51f8f2a..8d51eb9 100644
--- a/spi.h
+++ b/include/spi.h
@@ -4,15 +4,10 @@
#include "mcu/mcu_def.h"
#include "tasks.h"
-#include "buffers.h"
#ifndef _IOE_SPI_H_
#define _IOE_SPI_H_
-#ifdef CONFIG_IOE_SPI
-
-#ifndef MCUSUPPORT_SPI
-#error "No SPI interface is known on your mcu."
-#endif
+#ifdef CONFIG_SPI
enum spiMode {
SPI_MODE_MASTER,
@@ -20,6 +15,7 @@ enum spiMode {
};
volatile extern int8_t _spi_busy;
+volatile extern Mutex spi_mutex;
static inline void spi_init(enum spiMode mode) {
_spi_busy = 0;
@@ -45,13 +41,7 @@ static inline int8_t spi_busy(void) {
}
static inline void spi_join(void) {
- taskDelayTill(_spi_busy);
-}
-
-static inline uint8_t spi_send(uint8_t data) {
- spi_transfer(data);
- taskDelayTill(_spi_busy);
- return SPDR;
+ task_delay_till(&_spi_busy, 0);
}
static inline void spi_transfer(uint8_t data) {
@@ -59,11 +49,18 @@ static inline void spi_transfer(uint8_t data) {
SPDR = data;
}
+static inline uint8_t spi_send(uint8_t data) {
+ spi_transfer(data);
+ task_delay_till(&_spi_busy, 0);
+ return SPDR;
+}
+
static inline void spi_expose(uint8_t data) {
SPDR = data;
}
+// Null terminated array
extern void (*spi_receive)(uint8_t data);
-#endif /* CONFIG_IOE_SPI */
+#endif /* CONFIG_SPI */
#endif /* _IOE_SPI_H_ */
diff --git a/include/tasks.h b/include/tasks.h
new file mode 100644
index 0000000..27bd968
--- /dev/null
+++ b/include/tasks.h
@@ -0,0 +1,94 @@
+#include <avr/io.h>
+#include <util/delay.h>
+#include <avr/interrupt.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "mcu/mcu_def.h"
+#include "timer.h"
+
+#ifndef _IOE_TASKS_H_
+#define _IOE_TASKS_H_
+
+#ifdef CONFIG_IOE_TASKS
+
+#ifndef CONFIG_IOE_TIMERS
+#error "To use tasks you must enable timers (CONFIG_IOE_TIMERS)."
+#endif
+
+int8_t tasks_run(void);
+
+union StackPointer {
+ uint8_t lh8[2];
+ uint16_t lh16;
+};
+typedef struct {
+ uint8_t flags;
+ void (*func) (void *data);
+ void *data;
+ uint8_t _rflags;
+ uint8_t _stack_size;
+ union StackPointer _sp;
+} Task;
+int8_t task_spawn(Task * t, uint8_t stack_size);
+void taks_exit(void);
+int8_t task_kill(Task * t);
+int8_t task_safe(void);
+int8_t task_unsafe(void);
+
+int8_t task_delay(uint16_t cycles);
+int8_t task_delay_ms(uint16_t ms);
+int8_t task_delay_till(volatile int8_t * boolean, uint16_t ms);
+
+#define MUTEX_F_TIMED (1<<0)
+#define MUTEX_F_TAKEN (1<<7)
+typedef struct {
+ uint8_t flags;
+ Task *_task_took;
+} Mutex;
+int8_t mutex_init(Mutex * mtx);
+int8_t mutex_free(Mutex * mtx);
+int8_t mutex_take(Mutex * mtx, uint16_t timeout);
+int8_t mutex_give(Mutex * mtx);
+
+typedef struct {
+ uint8_t flags;
+ uint8_t _count;
+ Task **_tasks;
+ uint8_t _tasks_len;
+} Semaphore;
+int8_t semaphore_init(Semaphore * sem, uint8_t count);
+int8_t semaphore_free(Semaphore * sem);
+int8_t semaphore_take(Semaphore * sem, uint16_t timeout);
+int8_t semaphore_give(Semaphore * sem);
+
+#else /* CONFIG_IOE_TASKS */
+
+typedef struct {
+} Task;
+#define task_spawn(T, STACK_SIZE)
+#define task_exit()
+#define task_kill(T)
+#define task_safe()
+#define task_unsafe()
+
+#define task_delay(US) _delay_us(US) // TODO this should be cycles
+#define task_delay_ms(MS) _delay_ms(MS)
+int8_t task_delay_till(volatile int8_t * boolean, uint16_t ms);
+
+typedef struct {
+} Mutex;
+#define mutex_init(MTX, FLAGS)
+#define mutex_free(MTX)
+#define mutex_take(MTX, TIMEOUT)
+#define mutex_give(MTX);
+
+typedef struct {
+} Semaphore;
+#define semaphore_init(SEM, FLAGS, COUNT)
+#define semaphore_free(SEM)
+#define semaphore_take(SEM, TIMEOUT)
+#define semaphore_give(SEM)
+
+#endif /* CONFIG_IOE_TASKS */
+#endif /* _IOE_TASKS_H_ */
diff --git a/include/timer.h b/include/timer.h
new file mode 100644
index 0000000..4fef95c
--- /dev/null
+++ b/include/timer.h
@@ -0,0 +1,28 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <stdint.h>
+
+#include "mcu/mcu_def.h"
+#include "utils/narray.h"
+
+#ifndef _IOE_TIMER_H_
+#define _IOE_TIMER_H_
+#ifdef CONFIG_IOE_TIMERS
+
+enum timerDivider {
+ TIMER_DIVIDER_1,
+ TIMER_DIVIDER_8,
+ TIMER_DIVIDER_64,
+ TIMER_DIVIDER_256,
+ TIMER_DIVIDER_1024
+};
+
+void timer_init(uint8_t timer, enum timerDivider div);
+void timer_disable(uint8_t timer);
+void timer_reset(uint8_t timer);
+uint16_t timer_value(uint8_t timer);
+void timer_sethook(uint8_t timer, void (*fnc) (void));
+void timer_remhook(uint8_t timer, void (*fnc) (void));
+
+#endif /* CONFIG_IOE_TIMERS */
+#endif /* _IOE_TIMER_H_ */
diff --git a/twi.h b/include/twi.h
index 514b17a..0763c4b 100644
--- a/twi.h
+++ b/include/twi.h
@@ -3,7 +3,6 @@
#include <stdint.h>
#include "mcu/mcu_def.h"
-#include "buffers.h"
#ifndef _IOE_TWI_H_
#define _IOE_TWI_H_
diff --git a/usart.h b/include/usart.h
index a67b141..3ba5382 100644
--- a/usart.h
+++ b/include/usart.h
@@ -5,15 +5,11 @@
#include "mcu/mcu_def.h"
#include "tasks.h"
-#include "buffers.h"
+#include "utils/buffer.h"
-#ifndef _IOE_USART_H_
-#define _IOE_USART_H_
-#ifdef CONFIG_IOE_USART
-
-#ifndef MCUSUPPORT_USART
-#error "No USART interface is known on your mcu."
-#endif
+#ifndef _USART_H_
+#define _USART_H_
+#ifdef CONFIG_USART
// TODO clock polarity and synchronous mode
@@ -21,13 +17,13 @@
#define USART_DATAOVERRUN _BV(DOR0)
#define USART_PARITYERROR _BV(UPE0)
-#if CONFIG_IOE_USART_INBUFFER_SIZE > 0
-#define _IOE_USART_INBUFFER
-volatile IOEBUFFER(_ioe_usart_inbuffer, CONFIG_IOE_USART_INBUFFER_SIZE);
+#if CONFIG_USART_INBUFFER_SIZE > 0
+#define _USART_INBUFFER
+volatile IOEBUFFER(uint8_t, _ioe_usart_inbuffer, CONFIG_USART_INBUFFER_SIZE);
#endif
-#if CONFIG_IOE_USART_OUTBUFFER_SIZE > 0
-#define _IOE_USART_OUTBUFFER
-volatile IOEBUFFER(_ioe_usart_outbuffer, CONFIG_IOE_USART_OUTBUFFER_SIZE);
+#if CONFIG_USART_OUTBUFFER_SIZE > 0
+#define _USART_OUTBUFFER
+volatile IOEBUFFER(uint8_t, _ioe_usart_outbuffer, CONFIG_USART_OUTBUFFER_SIZE);
#endif
extern volatile int8_t _usart_busy;
@@ -38,10 +34,10 @@ extern volatile int8_t _usart_busy;
*/
void usart_init_async(void);
void usart_send(uint8_t data);
-#ifdef _IOE_USART_OUTBUFFER
+#ifdef _USART_OUTBUFFER
void usart_send_str(char *str);
#endif
-#ifdef _IOE_USART_INBUFFER
+#ifdef _USART_INBUFFER
uint8_t usart_get(void);
#endif
static inline uint8_t usart_queryerror(void) {
@@ -50,13 +46,13 @@ static inline uint8_t usart_queryerror(void) {
static inline int8_t usart_busy(void) {
return _usart_busy;
}
-#ifdef _IOE_USART_INBUFFER
+#ifdef _USART_INBUFFER
uint8_t usart_inbuffered(void);
#endif
-#ifdef _IOE_USART_OUTBUFFER
+#ifdef _USART_OUTBUFFER
uint8_t usart_outbuffered(void);
#endif
-#if (defined CONFIG_IOE_USART_INFILE) || (defined CONFIG_IOE_USART_OUTFILE)
+#if (defined CONFIG_USART_INFILE) || (defined CONFIG_USART_OUTFILE)
FILE *usart_async_open(void);
#endif
@@ -64,5 +60,5 @@ FILE *usart_async_open(void);
extern void (*usart_receive)(uint8_t data);
extern void (*usart_sent)(void);
-#endif /* CONFIG_IOE_USART */
-#endif /* _IOE_USART_H_ */
+#endif /* CONFIG_USART */
+#endif /* _USART_H_ */
diff --git a/usi_spi.h b/include/usi_spi.h
index 18534ab..18534ab 100644
--- a/usi_spi.h
+++ b/include/usi_spi.h
diff --git a/buffers.h b/include/utils/buffer.h
index 497a21c..66b68ad 100644
--- a/buffers.h
+++ b/include/utils/buffer.h
@@ -1,18 +1,10 @@
-/* This defines common buffer code for whole library.
- * It is preprocessor generated code.
- * Preprocessor variables chose different implementations. But final
- * implementation is only few lines of code. This way it is included directly
- * to code.
- */
-#include "tasks.h"
-
-#ifndef _IOE_BUFFERS_H_
-#define _IOE_BUFFERS_H_
+#ifndef _IOE_BUFFER_H_
+#define _IOE_BUFFER_H_
// Define new buffer
-#define IOEBUFFER(name, size) struct { \
+#define IOEBUFFER(type, name, size) struct { \
uint8_t rindex, windex; \
- uint8_t data[size]; \
+ type data[size]; \
} name;
#define IOEBUFFER_INIT(name, size) { \
@@ -24,7 +16,7 @@
#define IOEBUFFER_MODE_OVERWRITE 1
#define IOEBUFFER_MODE_DROP 2
// Add data to buffer. If buffer is full then behavior is defined by selected mode.
-#define IOEBUFFER_PUT(name, size, data, mode) \
+#define IOEBUFFER_PUT(name, size, idata, mode) \
if (mode == IOEBUFFER_MODE_BLOCK) { \
if (name.windex == 0) { \
while (name.rindex == size - 1); \
@@ -32,7 +24,7 @@
while (name.rindex == name.windex - 1); \
} \
} \
- name.data[name.windex] = data; \
+ name.data[name.windex] = idata; \
if (mode != IOEBUFFER_MODE_DROP || \
(name.windex == 0 && name.rindex == size - 1) || \
(name.rindex + 1 == name.windex)) { \
@@ -69,4 +61,26 @@
else \
variable = 0;
-#endif /* _IOE_BUFFERS_H_ */
+/////////////////////////////////////////////////////////////////////
+
+#ifdef CONFIG_IOE_BUFFER
+#include <stdint.h>
+
+#define IOEBUFFER_F_MODE_BLOCK 0x0
+#define IOEBUFFER_F_MODE_OVERWRITE 0x1
+#define IOEBUFFER_F_MODE_DROP 0x2
+
+typedef struct {
+ uint8_t rindex, windex, size, flags;
+ void **data;
+} IOEBuffer;
+
+int8_t ioebuffer_init(IOEBuffer * buf, uint8_t size, uint8_t flags);
+void ioebuffer_uninit(IOEBuffer * buf);
+int8_t ioebuffer_put(IOEBuffer * buf, void *data);
+int8_t ioebuffer_get(IOEBuffer * buf, void **data);
+void ioebuffer_clean(IOEBuffer * buf);
+uint8_t ioebuffer_cnt(IOEBuffer * buf);
+
+#endif /* CONFIG_IOE_BUFFER */
+#endif /* _IOE_BUFFER_H_ */
diff --git a/include/utils/narray.h b/include/utils/narray.h
new file mode 100644
index 0000000..814d87d
--- /dev/null
+++ b/include/utils/narray.h
@@ -0,0 +1,21 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifndef _IOE_NARRAY_H_
+#define _IOE_NARRAY_H_
+#ifdef CONFIG_IOE_NARRAY
+
+void narray_add(void ***array, void *data);
+void narray_remove(void ***array, void *data);
+size_t narray_size(void ***array);
+inline void narray_free(void ***array) {
+ if (array != NULL) {
+ free(*array);
+ *array = NULL;
+ }
+}
+
+#define fornarray(array, i, data) for (i = 0; (data = array[i]) != 0; i++)
+
+#endif /* CONFIG_IOE_NARRAY */
+#endif /* _IOE_NARRAY_H_ */
diff --git a/include/utils/timers_div.h b/include/utils/timers_div.h
new file mode 100644
index 0000000..9077aac
--- /dev/null
+++ b/include/utils/timers_div.h
@@ -0,0 +1,81 @@
+//#include "../timer.h"
+enum timerDivider {
+ TIMER_DIVIDER_1,
+ TIMER_DIVIDER_8,
+ TIMER_DIVIDER_64,
+ TIMER_DIVIDER_256,
+ TIMER_DIVIDER_1024
+};
+
+#ifndef TIMER_DIV_RESTIME
+#error Please define minimal time (us) before include timers_div.h in TIMER_DIV_RESTIME
+#endif
+
+// Calculate optimal division
+#define _TD_OPTIMAL (TIMER_DIV_RESTIME * F_CPU/1000000L)
+
+// Set minimal and maximal division closest to optimal
+#if _TD_OPTIMAL < 8
+#define _TD_MIN 1
+#define _TD_MAX 8
+#elif _TD_OPTIMAL < 64
+#define _TD_MIN 8
+#define _TD_MAX 64
+#elif _TD_OPTIMAL < 256
+#define _TD_MIN 64
+#define _TD_MAX 256
+#elif _TD_OPTIMAL < 1024
+#define _TD_MIN 256
+#define _TD_MAX 1024
+#else
+#define _TD_MIN 1024
+#define _TD_MAX 1024
+#endif
+
+// Calculate time difference between required time and got time resolution
+#define _TD_MIN_TIME (TIMER_DIV_RESTIME - (_TD_MIN * 1000000L / F_CPU))
+#define _TD_MAX_TIME (TIMER_DIV_RESTIME - (_TD_MAX * 1000000L / F_CPU))
+
+// Do absolute value of calculated numbers
+#if _TD_MIN_TIME < 0
+#define _TD_MIN_TIMEF (_TD_MIN_TIME * -1)
+#else
+#define _TD_MIN_TIMEF _TD_MIN_TIME
+#endif
+#if _TD_MAX_TIME < 0
+#define _TD_MAX_TIMEF (_TD_MAX_TIME * -1)
+#else
+#define _TD_MAX_TIMEF _TD_MAX_TIME
+#endif
+
+// Select closest one
+#if _TD_MIN_TIMEF < _TD_MAX_TIMEF
+#define _TD_TIMER_DIV _TD_MIN
+#else
+#define _TD_TIMER_DIV _TD_MAX
+#endif
+
+// Set macro to enum value
+#if _TD_TIMER_DIV == 1
+#define TIMER_DIV TIMER_DIVIDER_1
+#elif _TD_TIMER_DIV == 8
+#define TIMER_DIV TIMER_DIVIDER_8
+#elif _TD_TIMER_DIV == 64
+#define TIMER_DIV TIMER_DIVIDER_64
+#elif _TD_TIMER_DIV == 256
+#define TIMER_DIV TIMER_DIVIDER_256
+#elif _TD_TIMER_DIV == 1024
+#define TIMER_DIV TIMER_DIVIDER_1024
+#else
+#error Generated unknown timer division. Something is wrong with timers_div.h
+#endif
+
+// Undefine all used variables
+#undef _TD_OPTIMAL
+#undef _TD_MIN
+#undef _TD_MAX
+#undef _TD_MIN_TIME
+#undef _TD_MAX_TIME
+#undef _TD_MIN_TIMEF
+#undef _TD_MAX_TIMEF
+#undef _TD_TIMER_DIV
diff --git a/include/wireless/nrf24l01p.h b/include/wireless/nrf24l01p.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/include/wireless/nrf24l01p.h
diff --git a/kconfig b/kconfig
new file mode 160000
+Subproject 6814159a0a618a145aa5786a0ec3d311ce81ee9
diff --git a/makefile b/makefile
deleted file mode 100644
index 14aa590..0000000
--- a/makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-.PHONY: all help clean
-
-IOE_ONLYPATHS = y
-include avr-ioe.mk
-
-all:
- $(error This is not library, please include "avr-ioe.mk" to your project makefile. For more informations refer to README.md)
-
-help:
- @echo This makefile only implements these targets:
- @echo help - prints this text
- @echo clean - removing all object files generated from source files
-
-clean:
- $(RM) $(IOE_OBJ)
- $(RM) $(IOE_DEP)
diff --git a/mcu/ATmega328P.h b/mcu/ATmega328P.h
deleted file mode 100644
index e876295..0000000
--- a/mcu/ATmega328P.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This is specific configuration for ATmega328P.
- * Also applies on ATmega48A, ATmega48PA, ATmega88A, ATmega88PA, ATmega168A and
- * ATmega168PA.
- */
-#include <avr/io.h>
-
-// SPI
-#define MCUSUPPORT_SPI
-#define DDR_SPI DDRB
-#define DD_SS DDB2
-#define DD_MOSI DDB3
-#define DD_MISO DDB4
-#define DD_SCLK DDB5
-#define PORT_SPI PORTB
-#define PORT_SS PORTB2
-#define PORT_MOSI PORTB3
-#define PORT_MISO PORTB4
-#define PORT_SCLK PORTB5
-// USART
-#define MCUSUPPORT_USART
-// TWI
-#define MCUSUPPORT_TWI
-// TIMERS
-#define MCUSUPPORT_TIMER_0
-#define MCUSUPPORT_TIMER_1
-#define MCUSUPPORT_TIMER_2
-#define COUNTER0_PWM 0
-#define COUNTER1_16PWM 1
-#define COUNTER2_PWM_ASYNC 2
diff --git a/mcu/ATtiny4313.h b/mcu/ATtiny4313.h
deleted file mode 100644
index efbc01d..0000000
--- a/mcu/ATtiny4313.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This is specific configuration for ATtiny4313.
- * This configuration also applies on ATtiny2313A.
- */
-#include <avr/io.h>
-
-// SPI USI
-#define MCUSUPPORT_USI
-#define DDR_USI DDRB
-#define DD_DI DDB5
-#define DD_DO DDB6
-#define DD_USCK DDB7
-#define PORT_USI PORTB
-#define PORT_DI PORTB5
-#define PORT_DO PORTB6
-#define PORT_USCK PORTB7
-// USART
-#define MCUSUPPORT_USART0
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..a0724b4
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,20 @@
+site_name: AVR-IOE
+repo_url: https://github.com/Cynerd/avr-ioe.git
+site_description: AVR microcontroller input/output expansion code
+copyright: GNU General Public License, version 2.0
+pages:
+- Home: index.md
+- Usage: usage.md
+- Modules:
+ - IO Ports: modules/ioport.md
+ - SPI: modules/spi.md
+ - Tasks: modules/tasks.md
+ - Timer: modules/timer.md
+ - USART: modules/usart.md
+ - Utils:
+ - Buffer: modules/utils/buffer.md
+ - NArray: modules/utils/narray.md
+- Adding MCU support: add_support.md
+theme: readthedocs
+
+site_dir: html
diff --git a/src/adc.c b/src/adc.c
new file mode 100644
index 0000000..03e979e
--- /dev/null
+++ b/src/adc.c
@@ -0,0 +1,4 @@
+#include <adc.h>
+
+int8_t ioe_adc(uint8_t input) {
+}
diff --git a/src/can/mcp2515.c b/src/can/mcp2515.c
new file mode 100644
index 0000000..8c9915c
--- /dev/null
+++ b/src/can/mcp2515.c
@@ -0,0 +1,52 @@
+#include <can/mcp2515.h>
+
+#ifdef CONFIG_IOE_CAN_MCP2515
+// TODO check
+#define CAN_MCP2515_RESET 0xC0
+#define CAN_MCP2515_READ 0x03
+#define CAN_MCP2515_READRX 0x90
+#define CAN_MCP2515_WRITE 0x02
+#define CAN_MCP2515_LOADTX 0x40
+#define CAN_MCP2515_RTS 0x80
+#define CAN_MCP2515_RDSTAT 0xA0
+#define CAN_MCP2515_RXSTAT 0xB0
+#define CAN_MCP2515_BITMOD 0x05
+
+inline void can_mcp2515_init(canMcp2515 * can, uint8_t group, uint8_t mask) {
+ can->group = group;
+ can->mask = mask;
+ can_mcp2515_reset(can);
+ // TODO
+ return 0;
+};
+
+inline void can_mcp2515_reset(canMcp2515 * can) {
+ take_mutex(spi_mutex);
+ spi_join();
+
+ release_mutex(spi_mutex);
+};
+
+inline uint8_t can_mcp2515_read(canMcp2515 * can, uint8_t address) {
+};
+
+inline uint8_t can_mcp2515_readrx(canMcp2515 * can, uint8_t buffer) {
+};
+
+inline void can_mcp2515_write(canMcp2515 * can, uint8_t address, uint8_t data) {
+};
+
+inline void can_mcp2515_loadrx(canMcp2515 * can, uint8_t buffer, uint8_t data) {
+};
+
+inline uint8_t can_mcp2515_rdstat(canMcp2515 * can) {
+};
+
+inline uint8_t can_mcp2515_rxstat(canMcp2515 * can) {
+};
+
+inline void can_mcp2515_bitmod(canMcp2515 * can, uint8_t address, uint8_t mask,
+ uint8_t data) {
+};
+
+#endif /* CONFIG_IOE_CAN_MCP2515 */
diff --git a/src/ioport.c b/src/ioport.c
new file mode 100644
index 0000000..a77e564
--- /dev/null
+++ b/src/ioport.c
@@ -0,0 +1,113 @@
+#include <ioport.h>
+#ifdef CONFIG_IOPORTS
+#ifdef CONFIG_PCINT
+
+struct PCIW {
+ uint8_t flags;
+ uint8_t mask;
+ void (*change) (uint8_t group, uint8_t mask);
+};
+
+// Exploiting implementation of libc malloc
+#define PCIW_LEN(INPCIW) (*((uint16_t *) INPCIW - 1) / sizeof(struct PCIW) - 1)
+
+#if (defined MCUSUPPORT_PCINT0 && defined MCUSUPPORT_PCINT1 && defined MCUSUPPORT_PCINT2)
+#define PCI_COUNT 3
+#elif (defined MCUSUPPORT_PCINT0 && defined MCUSUPPORT_PCINT1 || \
+ defined MCUSUPPORT_PCINT1 && defined MCUSUPPORT_PCINT2 || \
+ defined MCUSUPPORT_PCINT2 && defined MCUSUPPORT_PCINT0)
+#define PCI_COUNT 2
+#elif (defined MCUSUPPORT_PCINT0 || defined MCUSUPPORT_PCINT1 || defined MCUSUPPORT_PCINT2)
+#define PCI_COUNT 1
+#else
+#define PCI_COUNT 0
+#endif
+
+#define GROUP2INDEX(GRP) (GRP - MCUSUPPORT_PCINT0)
+
+static struct PCIW *pciw[PCI_COUNT];
+static uint8_t pci_state[PCI_COUNT];
+static void pci(int8_t group, int8_t pinmax) {
+ int8_t i, y;
+ int8_t index = GROUP2INDEX(group);
+ int8_t len = (int8_t) PCIW_LEN(pciw[index]);
+ // WARN Is possible that PCINT0 is not corresponding with B group and so on?
+ uint8_t state = IOE_IO_PIN(group);
+ for (i = len; i >= 0; i--) {
+ uint8_t stA = state & pciw[index][i].mask;
+ uint8_t stB = pci_state[index] & pciw[index][i].mask;
+ if (((~stA & stB) && pciw[index][i].flags & IOE_IO_RISING) ||
+ ((stA & ~stB) && pciw[index][i].flags & IOE_IO_FALLING)) {
+ pciw[index][i].change(IOE_IO_B, mask);
+ }
+ }
+ pci_state[index] = state;
+}
+
+void io_change_sethook(uint8_t group, uint8_t mask, uint8_t edge,
+ void (*change) (uint8_t group, uint8_t mask)) {
+ int8_t index = (int8_t) GROUP2INDEX(group);
+ int8_t len = (int8_t) PCIW_LEN(pciw[index]);
+ pciw[index] = realloc(pciw[index], len + 1);
+ pciw[index][len].flags = edge;
+ pciw[index][len].mask = mask;
+ pciw[index][len].change = change;
+ switch (group) {
+#ifdef MCUSUPPORT_PCINT0 // TODO this wont work with attiny4313 and meaby others
+ case IO_B:
+ PCICR |= (1<<0);
+ PCMSK0 |= mask;
+ break;
+#endif
+#ifdef MCUSUPPORT_PCINT1
+ case IO_C:
+ PCICR |= (1<<1);
+ PCMSK1 |= mask;
+ break;
+#endif
+#ifdef MCUSUPPORT_PCINT2
+ case IO_D:
+ PCICR |= (1<<2);
+ PCMSK2 |= mask;
+ break
+#endif
+ }
+}
+
+void io_change_remhook(void (*change) (uint8_t group, uint8_t mask)) {
+ int8_t i, y;
+ int8_t len;
+ for (i = PCI_COUNT - 1; i >= 0; i--) {
+ len = (int8_t)PCIW_LEN(pciw[index]);
+ for (y = len - 1; y >= 0; y--) {
+ if (pciw[i][y].change == change) {
+
+ }
+ }
+ }
+}
+
+void io_change_clearhooks(void) {
+}
+
+// WARN This will work only if C is only defined on MCU with also B defined.
+#ifdef MCUSUPPORT_PCINT0
+ISR(PCINT0_vect, ISR_BLOCK) {
+ pci(IO_B, MCUSUPPORT_PCINT0);
+}
+#endif /* MCUSUPPORT_PCINT0 */
+
+#ifdef MCUSUPPORT_PCINT1
+ISR(PCINT1_vect, ISR_BLOCK) {
+ pci(IO_C, MCUSUPPORT_PCINT1);
+}
+#endif /* MCUSUPPORT_PCINT1 */
+
+#ifdef MCUSUPPORT_PCINT2
+ISR(PCINT2_vect, ISR_BLOCK) {
+ pci(IO_D, MCUSUPPORT_PCINT2);
+}
+#endif /* MCUSUPPORT_PCINT2 */
+
+#endif /* CONFIG_PCINT */
+#endif /* CONFIG_IOPORTS */
diff --git a/src/pcint.c b/src/pcint.c
deleted file mode 100644
index 1dedb63..0000000
--- a/src/pcint.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This file defines and handles Pin change interupts.
- * This interupt can be used in different modules and sensors. Function call can
- * be done from this interrupt handdler.
- */
-#include <avr/interrupt.h>
-
-#if (defined CONFIG_IOE_SENSOR_DHT22)
-
-#ifdef CONFIG_IOE_SENSOR_DHT22
-extern void dht22_read_pcint(void);
-#endif
-
-
-ISR(PCINT0_vect, ISR_BLOCK) {
-#ifdef CONFIG_IOE_SENSOR_DHT22
- void dht22_read_pcint();
-#endif
-}
-
-ISR(PCINT1_vect, ISR_BLOCK) {
-#ifdef CONFIG_IOE_SENSOR_DHT22
- void dht22_read_pcint();
-#endif
-}
-
-ISR(PCINT2_vect, ISR_BLOCK) {
-#ifdef CONFIG_IOE_SENSOR_DHT22
- void dht22_read_pcint();
-#endif
-}
-
-#endif
diff --git a/src/sensor_dht22.c b/src/sensors/dht22.c
index 7791060..9653ba5 100644
--- a/src/sensor_dht22.c
+++ b/src/sensors/dht22.c
@@ -1,4 +1,4 @@
-#include "../sensor_dht22.h"
+#include <sensors/dht22.h>
#ifdef CONFIG_IOE_SENSOR_DHT22
diff --git a/src/spi.c b/src/spi.c
index 4c0293c..69012fa 100644
--- a/src/spi.c
+++ b/src/spi.c
@@ -1,23 +1,19 @@
-#ifdef CONFIG_IOE_SPI
-#ifdef MCUSUPPORT_USART
+#include <spi.h>
+
+#ifdef CONFIG_SPI
volatile int8_t _spi_busy;
+volatile Mutex spi_mutex;
-////// Interrupts ////////////////////////////////
void (*spi_receive) (uint8_t data) = 0;
-#ifdef CONFIG_IOE_CAN_MCP2515
-extern void can_mcp2515_spi_hook(uint8_t);
-#endif /* CONFIG_IOE_CAN_MCP2515 */
-
ISR(SPI_STC_vect, ISR_BLOCK) {
+ void (*spir_w) (uint8_t data) = spi_receive;
_spi_busy = 0;
-#ifdef CONFIG_IOE_CAN_MCP2515
- can_mcp2515_spi_hook(SPDR);
-#endif /* CONFIG_IOE_CAN_MCP2515 */
- if (spi_receive)
- spi_receive(SPDR);
+ while (spir_w != NULL) {
+ spir_w(SPDR);
+ spir_w++;
+ }
}
-#endif /* MCUSUPPORT_SPI */
-#endif /* CONFIG_IOE_SPI */
+#endif /* CONFIG_SPI */
diff --git a/src/tasks.c b/src/tasks.c
index 1d94eaa..abc2add 100644
--- a/src/tasks.c
+++ b/src/tasks.c
@@ -1,16 +1,62 @@
-#include "../tasks.h"
-
+#include <tasks.h>
#ifdef CONFIG_IOE_TASKS
+void tasks_run(void) {
+}
+
+void task_init(Task * t, void (*func) (void)) {
+}
+void task_start(Task * t) {
+}
+
+void task_delay(uint16_t us) {
+}
+void task_delay_ms(uint16_t ms) {
+}
+void task_delay_till(volatile int8_t * boolean, uint16_t timeout) {
+}
+
+int8_t task_stack_init(TaskStack * ts, uint8_t stack_size, uint8_t flags) {
+ ts->stack = malloc(stack_size * sizeof(uint8_t));
+ ts->flags = flags;
+ ts->running = NULL;
+ ts->pending = NULL;
+}
+
+void task_stack_free(TaskStack * ts) {
+ free(ts->stack);
+}
+
+void task_stack_reg(TaskStack * ts, Task * t) {
+}
+
+void task_stack_unreg(TaskStack * ts, Task * t) {
+}
+
+void init_mutex(Mutex * mtx, uint8_t flags) {
+};
+void take_mutex(Mutex * mtx) {
+};
+int8_t take_mutex_t(Mutex * mtx, uint16_t timeout) {
+};
+void give_mutex(Mutex * mtx) {
+};
+
#else /* CONFIG_IOE_TASKS */
-int8_t taskDelayTillT(int8_t *condition, uint8_t timeout_10us) {
- while(*condition == 0) {
- if (timeout_10us == 0)
- return 1;
- timeout_10us--;
- _delay_us(10);
- }
+int8_t task_delay_till(volatile int8_t * boolean, uint16_t timeout) {
+ if (timeout == 0)
+ while (!*boolean)
+ _delay_us(100);
+ else
+ // TODO this implementation should be improved to check boolean as often
+ // as possible
+ while (*boolean == 0) {
+ if (timeout == 0)
+ return 1;
+ timeout--;
+ _delay_ms(1);
+ }
return 0;
}
diff --git a/src/timer.c b/src/timer.c
index 68c6c06..1175bad 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -1,7 +1,133 @@
-#include "../timer.h"
-
+#include <timer.h>
#ifdef CONFIG_IOE_TIMERS
+void timer_init(uint8_t timer, enum timerDivider div) {
+ switch (timer) {
+#ifdef COUNTER0_PWM
+ case COUNTER0_PWM:
+ // Null counting register
+ TCNT0 = 0;
+ // Set interrupt flag
+ TIMSK0 = _BV(TOIE0);
+ // Set division and start counting
+ switch (div) {
+ case TIMER_DIVIDER_1:
+ TCCR0B = _BV(CS00);
+ break;
+ case TIMER_DIVIDER_8:
+ TCCR0B = _BV(CS01);
+ break;
+ case TIMER_DIVIDER_64:
+ TCCR0B = _BV(CS01) | _BV(CS00);
+ break;
+ case TIMER_DIVIDER_256:
+ TCCR0B = _BV(CS02);
+ break;
+ case TIMER_DIVIDER_1024:
+ TCCR0B = _BV(CS02) | _BV(CS01);
+ break;
+ default:
+ return;
+ }
+ break;
+#endif /* COUNTER0_PWM */
+#ifdef COUNTER1_16PWM
+ case COUNTER1_16PWM:
+ break;
+#endif /* COUNTER1_16PWM */
+#ifdef COUNTER2_PWM_ASYNC
+ case COUNTER2_PWM_ASYNC:
+ break;
+#endif /* COUNTER2_PWM_ASYNC */
+ }
+}
+
+void timer_disable(uint8_t timer) {
+ switch (timer) {
+#ifdef COUNTER0_PWM
+ case COUNTER0_PWM:
+ TCCR0B = 0;
+ break;
+#endif /* COUNTER0_PWM */
+#ifdef COUNTER1_16PWM
+ case COUNTER1_16PWM:
+ break;
+#endif /* COUNTER1_16PWM */
+#ifdef COUNTER2_PWM_ASYNC
+ case COUNTER2_PWM_ASYNC:
+ break;
+#endif /* COUNTER2_PWM_ASYNC */
+ }
+}
+
+void timer_reset(uint8_t timer) {
+ switch (timer) {
+#ifdef COUNTER0_PWM
+ case COUNTER0_PWM:
+ TCNT0 = 0;
+ break;
+#endif /* COUNTER0_PWM */
+#ifdef COUNTER1_16PWM
+ case COUNTER1_16PWM:
+ break;
+#endif /* COUNTER1_16PWM */
+#ifdef COUNTER2_PWM_ASYNC
+ case COUNTER2_PWM_ASYNC:
+ break;
+#endif /* COUNTER2_PWM_ASYNC */
+ }
+}
+
+uint16_t timer_value(uint8_t timer) {
+ switch (timer) {
+#ifdef COUNTER0_PWM
+ case COUNTER0_PWM:
+ return TCNT0;
+ break;
+#endif /* COUNTER0_PWM */
+#ifdef COUNTER1_16PWM
+ case COUNTER1_16PWM:
+ break;
+#endif /* COUNTER1_16PWM */
+#ifdef COUNTER2_PWM_ASYNC
+ case COUNTER2_PWM_ASYNC:
+ break;
+#endif /* COUNTER2_PWM_ASYNC */
+ default:
+ return 0;
+ }
+}
+
+#ifdef COUNTER0_PWM
+static void *(*timer_0_pwm_overflow) (void);
+#endif /* COUNTER0_PWM */
+#ifdef COUNTER1_16PWM
+static void (*timer_1_16pwm_overflow) (void);
+#endif /* COUNTER1_16PWM */
+#ifdef COUNTER2_PWM_ASYNC
+static void (*timer_2_pwm_overflow) (void);
+#endif /* COUNTER2_PWM_ASYNC */
+
+void timer_sethook(uint8_t timer, void (*fnc) (void)) {
+ switch (timer) {
+#ifdef COUNTER0_PWM
+ case COUNTER0_PWM:
+ timer_0_pwm_overflow = fnc;
+ break;
+#endif /* COUNTER0_PWM */
+#ifdef COUNTER1_16PWM
+ case COUNTER1_16PWM:
+ timer_1_16pwm_overflow = fnc;
+ break;
+#endif /* COUNTER1_16PWM */
+#ifdef COUNTER2_PWM_ASYNC
+ case COUNTER2_PWM_ASYNC:
+ timer_2_pwm_overflow = fnc;
+ break;
+#endif /* COUNTER2_PWM_ASYNC */
+ }
+}
+
#ifdef COUNTER0_PWM
ISR(TIMER0_OVF_vect, ISR_BLOCK) {
if (timer_0_pwm_overflow)
diff --git a/src/usart.c b/src/usart.c
index bba83ac..6cfbc20 100644
--- a/src/usart.c
+++ b/src/usart.c
@@ -1,7 +1,5 @@
-#include "../usart.h"
-
-#ifdef CONFIG_IOE_USART
-#ifdef MCUSUPPORT_USART
+#include <usart.h>
+#ifdef CONFIG_USART
#define USART_PARITY_NONE 0
#define USART_PARITY_ODD 1
@@ -10,46 +8,46 @@
#define USART_STOPBIT_SINGLE 1
#define USART_STOPBIT_DOUBLE 2
-#ifndef CONFIG_IOE_USART_BAUD
-#warning "CONFIG_IOE_USART_BAUD not defined. Setting default 9600."
-#define CONFIG_IOE_USART_BAUD 9600
+#ifndef CONFIG_USART_BAUD
+#warning "CONFIG_USART_BAUD not defined. Setting default 9600."
+#define CONFIG_USART_BAUD 9600
#endif
-#ifndef CONFIG_IOE_USART_PARITY
-#warning "CONFIG_IOE_USART_PARITY not defined. Using default USART_PARITY_NONE."
-#define CONFIG_IOE_USART_PARITY USART_PARITY_NONE
+#ifndef CONFIG_USART_PARITY
+#warning "CONFIG_USART_PARITY not defined. Using default USART_PARITY_NONE."
+#define CONFIG_USART_PARITY USART_PARITY_NONE
#endif
-#ifndef CONFIG_IOE_USART_STOPBIT
-#warning "CONFIG_IOE_USART_STOPBIT not defined. Using default USART_STOPBIT_SINGLE."
-#define CONFIG_IOE_USART_STOPBIT USART_STOPBIT_SINGLE
+#ifndef CONFIG_USART_STOPBIT
+#warning "CONFIG_USART_STOPBIT not defined. Using default USART_STOPBIT_SINGLE."
+#define CONFIG_USART_STOPBIT USART_STOPBIT_SINGLE
#endif
-#ifndef CONFIG_IOE_USART_DATABITS
-#warning "CONFIG_IOE_USART_DATABITS not defined. Using default 8."
-#define CONFIG_IOE_USART_DATABITS 8
+#ifndef CONFIG_USART_DATABITS
+#warning "CONFIG_USART_DATABITS not defined. Using default 8."
+#define CONFIG_USART_DATABITS 8
#endif
-#if !((CONFIG_IOE_USART_PARITY == USART_PARITY_NONE) || \
- (CONFIG_IOE_USART_PARITY == USART_PARITY_ODD) || \
- (CONFIG_IOE_USART_PARITY == USART_PARITY_EVEN))
-#error "CONFIG_IOE_USART_PARITY has value, that is not allowed."
+#if !((CONFIG_USART_PARITY == USART_PARITY_NONE) || \
+ (CONFIG_USART_PARITY == USART_PARITY_ODD) || \
+ (CONFIG_USART_PARITY == USART_PARITY_EVEN))
+#error "CONFIG_USART_PARITY has value, that is not allowed."
#endif
-#if !((CONFIG_IOE_USART_STOPBIT == USART_STOPBIT_SINGLE) || \
- (CONFIG_IOE_USART_STOPBIT == USART_STOPBIT_DOUBLE))
-#error "CONFIG_IOE_USART_STOPBIT has value, that is not allowed."
+#if !((CONFIG_USART_STOPBIT == USART_STOPBIT_SINGLE) || \
+ (CONFIG_USART_STOPBIT == USART_STOPBIT_DOUBLE))
+#error "CONFIG_USART_STOPBIT has value, that is not allowed."
#endif
-#if !((CONFIG_IOE_USART_DATABITS == 5) || \
- (CONFIG_IOE_USART_DATABITS == 6) || \
- (CONFIG_IOE_USART_DATABITS == 7) || \
- (CONFIG_IOE_USART_DATABITS == 8))
+#if !((CONFIG_USART_DATABITS == 5) || \
+ (CONFIG_USART_DATABITS == 6) || \
+ (CONFIG_USART_DATABITS == 7) || \
+ (CONFIG_USART_DATABITS == 8))
// TODO DATABITS 9 is not supported
-#error "CONFIG_IOE_USART_DATABITS has value, that is not allowed."
+#error "CONFIG_USART_DATABITS has value, that is not allowed."
#endif
-#if (defined CONFIG_IOE_USART_INFILE) && (CONFIG_IOE_USART_INBUFFER_SIZE <= 0)
+#if (defined CONFIG_USART_INFILE) && (CONFIG_USART_INBUFFER_SIZE <= 0)
#error "USART Input file can't be enabled without input buffer"
#endif
-#if (defined CONFIG_IOE_USART_OUTFILE) && (CONFIG_IOE_USART_OUTBUFFER_SIZE <= 0)
+#if (defined CONFIG_USART_OUTFILE) && (CONFIG_USART_OUTBUFFER_SIZE <= 0)
#error "USART Input file can't be enabled without output buffer"
#endif
@@ -58,7 +56,7 @@ volatile int8_t _usart_busy;
void usart_init_async(void) {
_usart_busy = 0;
-#define BAUD CONFIG_IOE_USART_BAUD
+#define BAUD CONFIG_USART_BAUD
#include <util/setbaud.h>
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
@@ -70,95 +68,95 @@ void usart_init_async(void) {
UCSR0C = 0 |
// USART_PARITY_NONE are both UMP01 and UMP00 zero
-#if CONFIG_IOE_USART_PARITY == USART_PARITY_ODD
+#if CONFIG_USART_PARITY == USART_PARITY_ODD
_BV(UPM01) |
-#elif CONFIG_IOE_USART_PARITY == USART_PARITY_EVEN
+#elif CONFIG_USART_PARITY == USART_PARITY_EVEN
_BV(UPM00) | _BV(UPM01) |
#endif
// USART_STOPBIT_SINGLE is USBS0 zero
-#if CONFIG_IOE_USART_STOPBIT == USART_STOPBIT_DOUBLE
+#if CONFIG_USART_STOPBIT == USART_STOPBIT_DOUBLE
_BV(USBS0) |
#endif
// For 5 databits are UCSZ00 and UCSZ01 zero
-#if CONFIG_IOE_USART_DATABITS == 6
+#if CONFIG_USART_DATABITS == 6
_BV(UCSZ00)
-#elif CONFIG_IOE_USART_DATABITS == 7
+#elif CONFIG_USART_DATABITS == 7
_BV(UCSZ01)
-#elif CONFIG_IOE_USART_DATABITS == 8
+#elif CONFIG_USART_DATABITS == 8
_BV(UCSZ00) | _BV(UCSZ01)
#endif
;
// Enable receiver, transmitter and RX complete,
// Data register empty interrupts
UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0) | _BV(UDRIE0);
-#ifdef _IOE_USART_INBUFFER
- IOEBUFFER_INIT(_ioe_usart_inbuffer, CONFIG_IOE_USART_INBUFFER_SIZE);
+#ifdef _USART_INBUFFER
+ IOEBUFFER_INIT(_ioe_usart_inbuffer, CONFIG_USART_INBUFFER_SIZE);
#endif
-#ifdef _IOE_USART_OUTBUFFER
- IOEBUFFER_INIT(_ioe_usart_outbuffer, CONFIG_IOE_USART_OUTBUFFER_SIZE);
+#ifdef _USART_OUTBUFFER
+ IOEBUFFER_INIT(_ioe_usart_outbuffer, CONFIG_USART_OUTBUFFER_SIZE);
#endif
}
inline void usart_send(uint8_t data) {
-#ifdef _IOE_USART_OUTBUFFER
+#ifdef _USART_OUTBUFFER
if (!_usart_busy) {
_usart_busy = 1;
UDR0 = data;
} else {
IOEBUFFER_PUT(_ioe_usart_outbuffer,
- CONFIG_IOE_USART_OUTBUFFER_SIZE, data,
- CONFIG_IOE_USART_OUTBUFFER_MODE);
+ CONFIG_USART_OUTBUFFER_SIZE, data,
+ CONFIG_USART_OUTBUFFER_MODE);
}
#else
_usart_busy = 1;
UDR0 = data;
-#endif /* _IOE_USART_OUTBUFFER */
+#endif /* _USART_OUTBUFFER */
}
-#ifdef _IOE_USART_OUTBUFFER
+#ifdef _USART_OUTBUFFER
inline void usart_send_str(char *str) {
while (*str != '\0') {
usart_send((uint8_t) * str);
str++;
}
}
-#endif /* _IOE_USART_OUTBUFFER */
+#endif /* _USART_OUTBUFFER */
-#ifdef _IOE_USART_INBUFFER
+#ifdef _USART_INBUFFER
uint8_t usart_get(void) {
uint8_t rtn;
- IOEBUFFER_GET(_ioe_usart_inbuffer, CONFIG_IOE_USART_INBUFFER_SIZE,
+ IOEBUFFER_GET(_ioe_usart_inbuffer, CONFIG_USART_INBUFFER_SIZE,
rtn);
return rtn;
}
#endif
-#ifdef _IOE_USART_INBUFFER
+#ifdef _USART_INBUFFER
uint8_t usart_inbuffered(void) {
uint8_t rtn;
- IOEBUFFER_CNT(_ioe_usart_inbuffer, CONFIG_IOE_USART_INBUFFER_SIZE,
+ IOEBUFFER_CNT(_ioe_usart_inbuffer, CONFIG_USART_INBUFFER_SIZE,
rtn);
return rtn;
}
#endif
-#ifdef _IOE_USART_OUTBUFFER
+#ifdef _USART_OUTBUFFER
uint8_t usart_outbuffered(void) {
uint8_t rtn;
- IOEBUFFER_CNT(_ioe_usart_outbuffer, CONFIG_IOE_USART_OUTBUFFER_SIZE,
+ IOEBUFFER_CNT(_ioe_usart_outbuffer, CONFIG_USART_OUTBUFFER_SIZE,
rtn);
return rtn;
}
#endif
-#ifdef CONFIG_IOE_USART_OUTFILE
+#ifdef CONFIG_USART_OUTFILE
static int usartput(char c, FILE * f) {
usart_send((uint8_t) c);
return 0;
}
#endif
-#ifdef CONFIG_IOE_USART_INBUFFER
+#ifdef CONFIG_USART_INBUFFER
static int usartget(FILE * f) {
uint8_t v;
while (!(v = usart_get()));
@@ -166,11 +164,11 @@ static int usartget(FILE * f) {
}
#endif
-#if (defined CONFIG_IOE_USART_INFILE) || (defined CONFIG_IOE_USART_OUTFILE)
+#if (defined CONFIG_USART_INFILE) || (defined CONFIG_USART_OUTFILE)
FILE *usart_async_open(void) {
usart_init_async();
-#ifdef CONFIG_IOE_USART_OUTFILE
-#ifdef CONFIG_IOE_USART_INFILE
+#ifdef CONFIG_USART_OUTFILE
+#ifdef CONFIG_USART_INFILE
return fdevopen(usartput, usartget);
#else
return fdevopen(usartput, 0);
@@ -186,19 +184,19 @@ void (*usart_receive) (uint8_t data) = 0;
void (*usart_sent) (void) = 0;
SIGNAL(USART_RX_vect) {
-#ifdef _IOE_USART_INBUFFER
+#ifdef _USART_INBUFFER
uint8_t val = UDR0;
- IOEBUFFER_PUT(_ioe_usart_inbuffer, CONFIG_IOE_USART_INBUFFER_SIZE,
- val, CONFIG_IOE_USART_INBUFFER_MODE);
-#endif /* _IOE_USART_INBUFFER */
+ IOEBUFFER_PUT(_ioe_usart_inbuffer, CONFIG_USART_INBUFFER_SIZE,
+ val, CONFIG_USART_INBUFFER_MODE);
+#endif /* _USART_INBUFFER */
if (usart_receive)
usart_receive(UDR0);
}
SIGNAL(USART_UDRE_vect) {
-#ifdef _IOE_USART_OUTBUFFER
+#ifdef _USART_OUTBUFFER
uint8_t val;
- IOEBUFFER_GET(_ioe_usart_outbuffer, CONFIG_IOE_USART_OUTBUFFER_SIZE,
+ IOEBUFFER_GET(_ioe_usart_outbuffer, CONFIG_USART_OUTBUFFER_SIZE,
val);
if (val)
UDR0 = val;
@@ -206,10 +204,9 @@ SIGNAL(USART_UDRE_vect) {
_usart_busy = 0;
#else
_usart_busy = 0;
-#endif /* _IOE_USART_OUTBUFFER */
+#endif /* _USART_OUTBUFFER */
if (usart_sent)
usart_sent();
}
-#endif /* MCUSUPPORT_USART */
-#endif /* CONFIG_IOE_USART */
+#endif /* CONFIG_USART */
diff --git a/src/usi_spi.c b/src/usi_spi.c
index 01c37f7..3291721 100644
--- a/src/usi_spi.c
+++ b/src/usi_spi.c
@@ -1,5 +1,5 @@
-#include "../usi_spi.h"
-#include "../mcu/mcu_def.h"
+#include <usi_spi.h>
+#include <mcu/mcu_def.h>
inline void usi_spi_init(enum spiMode mode) {
if (mode == USI_SPI_MODE_MASTER) {
diff --git a/src/utils/buffer.c b/src/utils/buffer.c
new file mode 100644
index 0000000..3a5c15e
--- /dev/null
+++ b/src/utils/buffer.c
@@ -0,0 +1,70 @@
+#include <utils/buffer.h>
+
+#ifdef CONFIG_IOE_BUFFER
+
+int8_t ioebuffer_init(IOEBuffer * buf, uint8_t size, uint8_t flags) {
+ buf->windex = 0;
+ buf->rindex = 0;
+ buf->size = size;
+ buf->flags = flags;
+ buf->data = malloc(size * sizeof(void *));
+}
+
+void ioebuffer_uninit(IOEBuffer * buf) {
+ free(buf->data);
+}
+
+int8_t ioebuffer_put(IOEBuffer * buf, void *data) {
+ uint8_t mode = buf->flags & 0x3;
+ if (mode == IOEBUFFER_F_MODE_BLOCK) {
+ if (bud->windex == 0) {
+ while (bud->rindex == size - 1);
+ } else {
+ while (bud->rindex == bud->windex - 1);
+ }
+ }
+ bud->data[bud->windex] = data;
+ if (mode != IOEBUFFER_F_MODE_DROP ||
+ (bud->windex == 0 && bud->rindex == size - 1) ||
+ (bud->rindex + 1 == bud->windex)) {
+ if (bud->windex == 0)
+ bud->windex = size - 1;
+ else
+ bud->windex--;
+ }
+ if (mode == IOEBUFFER_F_MODE_OVERWRITE && bud->windex == bud->rindex) {
+ if (bud->windex == size - 1)
+ bud->windex = 0;
+ else
+ bud->windex++;
+ } else
+ return -1;
+ return 0;
+}
+
+int8_t ioebuffer_get(IOEBuffer * buf, void **data) {
+ if (buf->rindex != buf->windex) {
+ *data = buf->data[buf->rindex];
+ if (buf->rindex == 0)
+ buf->rindex = buf->size - 1;
+ else
+ buf->rindex--;
+ } else
+ *data = NULL;
+}
+
+void ioebuffer_clean(IOEBuffer * buf) {
+ buf->windex = 0;
+ bud->rindex = 0;
+}
+
+uint8_t ioebuffer_cnt(IOEBuffer * buf) {
+ if (buf->windex < buf->rindex)
+ return buf->rindex - buf->windex;
+ else if (buf->windex > buf->rindex)
+ return buf->size - buf->windex + buf->rindex;
+ else
+ return 0;
+}
+
+#endif /* CONFIG_IOE_BUFFER */
diff --git a/src/utils/narray.c b/src/utils/narray.c
new file mode 100644
index 0000000..f2cf0ed
--- /dev/null
+++ b/src/utils/narray.c
@@ -0,0 +1,36 @@
+#include <utils/narray.h>
+
+#ifdef CONFIG_IOE_NARRAY
+
+void narray_add(void ***array, void *data) {
+ if (*array == NULL) {
+ *array = malloc(2 * sizeof(void *));
+ (*array)[0] = data;
+ (*array)[1] = NULL;
+ } else {
+ uint8_t size = narray_size(array);
+ *array = realloc(*array, (size + 2) * sizeof(void *));
+ (*array)[size] = data;
+ (*array)[size + 1] = NULL;
+ }
+}
+
+void narray_remove(void ***array, void *data) {
+ uint8_t i = 0;
+ while ((*array)[i] != NULL || (*array)[i] != data)
+ i++;
+ while ((*array)[i + 1] != NULL) {
+ (*array)[i] = (*array)[i + 1];
+ i++;
+ }
+ (*array)[i] = NULL;
+ *array = realloc(*array, (i + 1) * sizeof(void *));
+}
+
+uint8_t narray_size(void ***array) {
+ uint8_t size = 0;
+ while ((*array)[size++] != NULL);
+ return size;
+}
+
+#endif /* CONFIG_IOE_NARRAY */
diff --git a/tasks.h b/tasks.h
deleted file mode 100644
index 60653b3..0000000
--- a/tasks.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <avr/io.h>
-#include <util/delay.h>
-#include <avr/interrupt.h>
-#include <stdint.h>
-
-#include "mcu/mcu_def.h"
-#include "timer.h"
-
-#ifndef _IOE_TASKS_H_
-#define _IOE_TASKS_H_
-#ifdef CONFIG_IOE_TASKS
-
-#ifndef CONFIG_IOE_TIMERS
-#error "To use tasks you must enable timers (CONFIG_IOE_TIMERS)."
-#endif
-
-struct Task {
-
-};
-
-void taskDelay(uint16_t us);
-void taskDelayMS(uint16_t ms);
-void taskDelayTill(int8_t *boolean);
-int8_t taskDelayTillT(int8_t *boolean, uin16_t us);
-void taskDelayTillF(int8_t (*fnc)(void));
-void taskDelayTillFT(int8_t (*fnc)(void), uint16_t us);
-
-struct Mutex {
-};
-void takeMutex(void);
-int8_t takeMutexT(uint16_t timeout);
-void giveMutex(void);
-
-struct Semaphore {
-};
-
-#else /* CONFIG_IOE_TASKS */
-
-#define taskDelay(US) _delay_us(US)
-#define taskDelayTill(BOOL) while(*BOOL == 0)
-int8_t taskDelayTillT(int8_t *condition, uint8_t timeout_10us);
-
-#endif /* CONFIG_IOE_TASKS */
-#endif /* _IOE_TASKS_H_ */
diff --git a/template/Makefile b/template/Makefile
new file mode 100644
index 0000000..f67d0c2
--- /dev/null
+++ b/template/Makefile
@@ -0,0 +1,72 @@
+MAKEFLAGS += --no-builtin-rules
+# Change PROJNAME value to you project name
+# Care to not make any space at the end!
+PROJNAME = template
+
+# Add new source files to this variable
+SRC = main.c
+
+OBJ = $(patsubst %.c,%.o,$(SRC)) # This creates list of *.o files from *.c
+
+.PHONY: all
+ifneq ("$(wildcard .config)","") # Checking if configuration exists
+all: $(PROJNAME).hex
+ @echo Now you can flash $< to your chip.
+else
+all: help .config
+endif
+
+# Edit here help like you ever want
+.PHONY: help
+help:
+ @echo "This is avr-ioe template project"
+ @echo " all - Build project"
+ @echo " config - Start configuration program"
+ @echo " menuconfig - NCurses based configuration program"
+ @echo " help - Prints this text"
+ @echo " clean - Removing all object files generated from source files"
+
+.PHONY: clean
+clean:
+ @echo " CLEAN OBJ"
+ @$(RM) $(OBJ)
+ @echo " CLEAN $(PROJNAME).elf $(PROJNAME).hex"
+ @$(RM) $(PROJNAME).elf $(PROJNAME).hex
+ @$(MAKE) -C avr-ioe clean
+
+# Building targets are available only if configuration is generated
+ifneq ("$(wildcard .config)","")
+-include .config
+# If you want change some standard CFLAGS, change them in configuration not here.
+# Add here only options that should not be applied to avr-ioe also.
+CFLAGS = -Iavr-ioe/include -mmcu=$(MMCU) -imacros avr-ioe/.config.h \
+ $(shell echo $(CONFCFLAGS)) $(shell echo -DF_CPU=$(F_CPU)000L)
+
+$(PROJNAME).elf: avr-ioe/libioe.a
+$(PROJNAME).elf: $(OBJ)
+ @echo " LD $@"
+ @avr-gcc -Os -mmcu=$(MMCU) $^ -o $@ -Lavr-ioe -lioe
+
+$(PROJNAME).hex: $(PROJNAME).elf
+ @echo " OBJCOPY $@"
+ @avr-objcopy -O ihex -R .eeprom $< $@
+
+$(OBJ): %.o: %.c avr-ioe/libioe.a
+ @echo " CC $@"
+ @avr-gcc $(CFLAGS) -c -o $@ $<
+
+avr-ioe/libioe.a: .config
+ @CONFIG=$$(readlink -f .config) $(MAKE) -C avr-ioe libioe.a
+endif
+
+.config:
+ @echo Please generate configuration first using config or menuconfig target
+ @exit 1
+
+.PHONY: config
+config:
+ @CONFIG=$$(readlink -f .config) $(MAKE) -C avr-ioe menuconfig
+
+.PHONY: menuconfig
+menuconfig:
+ @CONFIG=$$(readlink -f .config) $(MAKE) -C avr-ioe menuconfig
diff --git a/template/README.md b/template/README.md
new file mode 100644
index 0000000..bdafb7f
--- /dev/null
+++ b/template/README.md
@@ -0,0 +1,9 @@
+AVR-IOE template project
+========================
+Use can use this as template for our project. Just move it where you want it and
+change symbolic link to avr-ioe. Or if you are going to use git, just remove
+symbolic link and add avr-ioe as submodule.
+
+In Makefile you can change project name and add or change source files.
+
+To configure avr-ioe just run `make menuconfig` in this folder.
diff --git a/template/avr-ioe b/template/avr-ioe
new file mode 120000
index 0000000..a96aa0e
--- /dev/null
+++ b/template/avr-ioe
@@ -0,0 +1 @@
+.. \ No newline at end of file
diff --git a/template/main.c b/template/main.c
new file mode 100644
index 0000000..90bb878
--- /dev/null
+++ b/template/main.c
@@ -0,0 +1,5 @@
+#include <avr-ioe.h>
+
+int main() {
+ return 0;
+};
diff --git a/time.h b/time.h
deleted file mode 100644
index 945511d..0000000
--- a/time.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <stdint.h>
-
-#include "mcu/mcu_def.h"
-
-#ifndef _IOE_TIME_H_
-#define _IOE_TIME_H_
-
-#ifndef CONFIG_IOE_TIME_TIMER
-#error "To use Time you must specify CONFIG_IOE_TIME_TIMER macro."
-#endif
-
-
-#endif /* _IOE_TIME_H_ */
diff --git a/timer.h b/timer.h
deleted file mode 100644
index 192c15d..0000000
--- a/timer.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <stdint.h>
-
-#include "mcu/mcu_def.h"
-
-#ifndef _IOE_TIMER_H_
-#define _IOE_TIMER_H_
-#ifdef CONFIG_IOE_TIMERS
-
-enum timerDivider {
- TIMER_DIVIDER_1,
- TIMER_DIVIDER_8,
- TIMER_DIVIDER_64,
- TIMER_DIVIDER_256,
- TIMER_DIVIDER_1024
-};
-
-static inline void timer_init(uint8_t timer, enum timerDivider div) {
- switch (timer) {
-#ifdef COUNTER0_PWM
- case COUNTER0_PWM:
- // Null counting register
- TCNT0 = 0;
- // Set interrupt flag
- TIMSK0 = _BV(TOIE0);
- // Set division and start counting
- switch (div) {
- case TIMER_DIVIDER_1:
- TCCR0B = _BV(CS00);
- break;
- case TIMER_DIVIDER_8:
- TCCR0B = _BV(CS01);
- break;
- case TIMER_DIVIDER_64:
- TCCR0B = _BV(CS01) | _BV(CS00);
- break;
- case TIMER_DIVIDER_256:
- TCCR0B = _BV(CS02);
- break;
- case TIMER_DIVIDER_1024:
- TCCR0B = _BV(CS02) | _BV(CS01);
- break;
- default:
- return;
- }
- break;
-#endif /* COUNTER0_PWM */
-#ifdef COUNTER1_16PWM
- case COUNTER1_16PWM:
- break;
-#endif /* COUNTER1_16PWM */
-#ifdef COUNTER2_PWM_ASYNC
- case COUNTER2_PWM_ASYNC:
- break;
-#endif /* COUNTER2_PWM_ASYNC */
- }
-}
-
-static inline void timer_disable(uint8_t timer) {
- switch (timer) {
-#ifdef COUNTER0_PWM
- case COUNTER0_PWM:
- TCCR0B = 0;
- break;
-#endif /* COUNTER0_PWM */
-#ifdef COUNTER1_16PWM
- case COUNTER1_16PWM:
- break;
-#endif /* COUNTER1_16PWM */
-#ifdef COUNTER2_PWM_ASYNC
- case COUNTER2_PWM_ASYNC:
- break;
-#endif /* COUNTER2_PWM_ASYNC */
- }
-}
-
-static inline void timer_reset(uint8_t timer) {
- switch (timer) {
-#ifdef COUNTER0_PWM
- case COUNTER0_PWM:
- TCNT0 = 0;
- break;
-#endif /* COUNTER0_PWM */
-#ifdef COUNTER1_16PWM
- case COUNTER1_16PWM:
- break;
-#endif /* COUNTER1_16PWM */
-#ifdef COUNTER2_PWM_ASYNC
- case COUNTER2_PWM_ASYNC:
- break;
-#endif /* COUNTER2_PWM_ASYNC */
- }
-}
-
-static inline uint16_t timer_value(uint8_t timer) {
- switch (timer) {
-#ifdef COUNTER0_PWM
- case COUNTER0_PWM:
- return TCNT0;
- break;
-#endif /* COUNTER0_PWM */
-#ifdef COUNTER1_16PWM
- case COUNTER1_16PWM:
- break;
-#endif /* COUNTER1_16PWM */
-#ifdef COUNTER2_PWM_ASYNC
- case COUNTER2_PWM_ASYNC:
- break;
-#endif /* COUNTER2_PWM_ASYNC */
- default:
- return 0;
- }
-}
-
-#ifdef COUNTER0_PWM
-void (*timer_0_pwm_overflow) (void);
-#endif /* COUNTER0_PWM */
-#ifdef COUNTER1_16PWM
-void (*timer_1_16pwm_overflow) (void);
-#endif /* COUNTER1_16PWM */
-#ifdef COUNTER2_PWM_ASYNC
-void (*timer_2_pwm_overflow) (void);
-#endif /* COUNTER2_PWM_ASYNC */
-
-static inline void timer_sethook(uint8_t timer, void (*fnc) (void)) {
- switch (timer) {
-#ifdef COUNTER0_PWM
- case COUNTER0_PWM:
- timer_0_pwm_overflow = fnc;
- break;
-#endif /* COUNTER0_PWM */
-#ifdef COUNTER1_16PWM
- case COUNTER1_16PWM:
- timer_1_16pwm_overflow = fnc;
- break;
-#endif /* COUNTER1_16PWM */
-#ifdef COUNTER2_PWM_ASYNC
- case COUNTER2_PWM_ASYNC:
- timer_2_pwm_overflow = fnc;
- break;
-#endif /* COUNTER2_PWM_ASYNC */
- }
-}
-
-#endif /* CONFIG_IOE_TIMERS */
-#endif /* _IOE_TIMER_H_ */