Skip to content
Snippets Groups Projects
Commit e78ba71a authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Add common avr stuff

parent 8dffe83f
No related branches found
No related tags found
No related merge requests found
#
# Define the following in your makefile and then include this file
# TARGETS=<list of targets to be built>
#
# <TARGET>.ARCH=<architecture for target (avr)>
# <TARGET>.CHIP=<chip used for target>
# <TARGET>.FUSE=<fuse settings for target>
# <TARGET>.C=<.c files for target>
# <TARGET>.H=<.h file for target>
# Factory defaults for various chips
# factory_mega16.FUSE=--wr_fuse_l=0xe1 --wr_fuse_h=0x99 --wr_fuse_e=0xff
ifeq ($(TARGET),)
all: $(TARGETS:%=%.LINK)
%.LINK:
@mkdir -p compiled/$*
make --no-print-directory TARGET=$* $*.LINK
%.VERIFY:
@mkdir -p compiled/$*
make --no-print-directory TARGET=$* $*.VERIFY
%.LOAD:
@mkdir -p compiled/$*
make --no-print-directory TARGET=$* $*.LOAD
%.FUSE:
make --no-print-directory TARGET=$* $*.FUSE
else
avr-CC=avr-gcc
avr-CCFLAGS=-mmcu=$(CHIP) -g -Wall -Werror -O3 -I. -I../lib
avr-OBJCOPY=avr-objcopy
ARCH=$($(TARGET).ARCH)
CHIP=$($(TARGET).CHIP)
CC=$($(ARCH)-CC)
CCFLAGS=$($(ARCH)-CCFLAGS) $($(TARGET).CCFLAGS)
OBJCOPY=$($(ARCH)-OBJCOPY)
SOURCES=$($(1).C:%=%.c) $($(1).H:%=%.h)
OBJECTS=$($(1).C:%=compiled/$(1)/%.o)
%.LINK: compiled/$(TARGET)/%.exe
echo $@
%.LOAD_uisp: compiled/$(TARGET)/%.sr
uisp \
-dprog=stk200 \
--erase \
--upload if=compiled/$(TARGET)/$*.sr
%.VERIFY: compiled/$(TARGET)/%.sr
avrdude -P usb -c avrisp2 -p $(CHIP) \
-U flash:v:compiled/$(TARGET)/$*.sr:s
%.LOAD: compiled/$(TARGET)/%.sr
avrdude -P usb -c avrisp2 -p $(CHIP) \
-U flash:w:compiled/$(TARGET)/$*.sr:s
%.FUSE:
uisp \
-dprog=stk200 \
$($(TARGET).FUSE)
compiled/$(TARGET)/%.o: $(call SOURCES,$(TARGET))
$(CC) $(CCFLAGS) -o $@ -c $*.c
compiled/$(TARGET)/%.exe: $(call OBJECTS,$(TARGET))
$(CC) $(CCFLAGS) -o $@ $(call OBJECTS,$*)
compiled/$(TARGET)/%.sr: compiled/$(TARGET)/%.exe
$(OBJCOPY) -O srec $< $@
.PRECIOUS: compiled/$(TARGET)/%.o \
compiled/$(TARGET)/%.exe \
compiled/$(TARGET)/%.sr
endif
\ No newline at end of file
Digital in/out and poll commands are sent as one byte:
+-+-+-+-+-+-+-+-+
|0|0 0| chan | Bit clear
+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+
|0|0 1| chan | Bit set
+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+
|0|1 0| chan | Bit get
+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+
|0|1 1| chan | Channel get
+-+-+-+-+-+-+-+-+
Channels are sent as 2 to 6 bytes, depending on resolution:
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2 |1| bit8...bit2 | |0|bit| chan |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3 |1|bit15...bit9 | |1| bit8...bit2 | |0|bit| chan |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
...
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
6 |1|bit31...bit30| |1|bit29...bit23| ... |0|bit| chan |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
Channel 31 is special, as it serves as the configuration channel. When
reading from it multiple responses are sent with the following layout
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
| command specific data |cmd|kind |conf chan|
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
kind: 000 == end of configuration
001 == digital in
010 == digital out
011 == analog in
100 == analog out
101 == counter in
cmd == 0 (Resolution)
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
| | # of bits |0 0|kind |conf chan|
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
# of bits (1..32)
cmd == 1 (Minimum value)
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
| minimum |S| unit|0 1|kind |conf chan|
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
S (sign): 0 == +
1 == -
unit: 000 == V
001 == mV
010 == uV
cmd == 2 (Maximum value)
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
| maximum |S| unit|1 0|kind |conf chan|
+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
S (sign): 0 == +
1 == -
unit: 000 == V
001 == mV
010 == uV
/*
* Digital in/out and poll commands are sent as one byte:
*
* +-+-+-+-+-+-+-+-+
* |0|0 0| chan | Bit clear
* +-+-+-+-+-+-+-+-+
*
* +-+-+-+-+-+-+-+-+
* |0|0 1| chan | Bit set
* +-+-+-+-+-+-+-+-+
*
* +-+-+-+-+-+-+-+-+
* |0|1 0| chan | Bit get
* +-+-+-+-+-+-+-+-+
*
* +-+-+-+-+-+-+-+-+
* |0|1 1| chan | Channel get
* +-+-+-+-+-+-+-+-+
*
*
* Channels are sent as 2 to 6 bytes, depending on resolution:
*
* +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
* 2 |1| bit8...bit2 | |0|bit| chan |
* +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
*
* +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
* 3 |1|bit15...bit9 | |1| bit8...bit2 | |0|bit| chan |
* +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
*
* ...
*
* +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
* 6 |1|bit31...bit30| |1|bit29...bit23| ... |0|bit| chan |
* +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
*
*
*
* Channel 31 is special, as it serves as the configuration channel. When
* reading from it multiple responses are sent with the following layout
*
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
* | command specific data |cmd|kind |conf chan|
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
*
* kind: 000 == end of configuration
* 001 == digital in
* 010 == digital out
* 011 == analog in
* 100 == analog out
* 101 == counter in
*
*cmd == 0 (Resolution)
*
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
* | | # of bits |0 0|kind |conf chan|
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
*
* # of bits (1..32)
*
*cmd == 1 (Minimum value)
*
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
* | minimum |S| unit|0 1|kind |conf chan|
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
*
* S (sign): 0 == +
* 1 == -
* unit: 000 == V
* 001 == mV
* 010 == uV
* 100 == A
*
*cmd == 2 (Maximum value)
*
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
* | maximum |S| unit|1 0|kind |conf chan|
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
*
* S (sign): 0 == +
* 1 == -
* unit: 000 == V
* 001 == mV
* 010 == uV
* 100 == A
*/
static volatile unsigned long serialio_value;
static volatile unsigned char serialio_channel, serialio_length;
static void serialio_putchar(unsigned char ch)
{
while ((in(UCSRA) & 0x20) == 0) {};
out(UDR, ch);
}
static void serialio_putbit(unsigned char channel, unsigned char value)
{
if (value) {
serialio_putchar(0x20 | (channel & 0x1f));
} else {
serialio_putchar(0x00 | (channel & 0x1f));
}
}
static void serialio_putchannel(unsigned char channel, unsigned long value)
{
if (value >= (1L<<30)) { serialio_putchar(0x80 | ((value >> 30) & 0x03)); }
if (value >= (1L<<23)) { serialio_putchar(0x80 | ((value >> 23) & 0x7f)); }
if (value >= (1L<<16)) { serialio_putchar(0x80 | ((value >> 16) & 0x7f)); }
if (value >= (1L<< 9)) { serialio_putchar(0x80 | ((value >> 9) & 0x7f)); }
serialio_putchar(0x80 | ((value >> 2) & 0x7f));
serialio_putchar(((value << 5) & 0x60) | (channel & 0x1f));
}
#define CONF_DIG_IN(channel) (0x20 | (channel)&0x1f)
#define CONF_DIG_OUT(channel) (0x40 | (channel)&0x1f)
#define CONF_END() serialio_putchannel(31, 0)
#define CONF_DIGITAL_IN(chan, config) \
serialio_putchannel(31, (0x20|(chan&0x1f)|(config&0xffffff00)))
#define CONF_DIGITAL_OUT(chan, config) \
serialio_putchannel(31, (0x40|(chan&0x1f)|(config&0xffffff00)))
#define CONF_ANALOG_IN(chan, config) \
serialio_putchannel(31, (0x60|(chan&0x1f)|(config&0xffffff00)))
#define CONF_ANALOG_OUT(chan, config) \
serialio_putchannel(31, (0x80|(chan&0x1f)|(config&0xffffff00)))
#define CONF_ENCODER_IN(chan, config) \
serialio_putchannel(31, (0xa0|(chan&0x1f)|(config&0xffffff00)))
#define CONF_RESOLUTION(bits) (((bits)<<10)|0x000)
#define CONF_MIN(value) ((value)|0x100)
#define CONF_MAX(value) ((value)|0x200)
#define CONF_NEGATIVE_VOLT(volt) (((long)(volt)<<14)|0x2000)
#define CONF_POSITIVE_VOLT(volt) ((long)(volt)<<14)
#define CONF_NEGATIVE_MILLIVOLT(millivolt) (((long)(millivolt)<<14)|0x2400)
#define CONF_POSITIVE_MILLIVOLT(millivolt) ((long)(millivolt)<<14|0x400)
#define CONF_POSITIVE_AMPERE(ampere) (((long)(ampere)<<14)|0x1000)
static void serialio_init()
{
serialio_value = 0;
serialio_channel = 255;
serialio_length = 0;
}
typedef enum {
serialio_error, serialio_more, serialio_clearbit, serialio_setbit,
serialio_setchannel, serialio_pollbit, serialio_pollchannel
} serialio_rxc_status;
static serialio_rxc_status serialio_RXC(unsigned char ch) {
unsigned char result = serialio_error;
if (serialio_length == 0) { serialio_value = 0; }
serialio_length++;
if ((ch & 0x80) == 0x80) {
// Collect yet another byte for later processing
serialio_value = (serialio_value << 7) | (ch & 0x7f);
result = serialio_more;
} else {
serialio_value = (serialio_value << 2) | ((ch & 0x60) >> 5);
serialio_channel = ch & 0x1f;
if (serialio_length == 1) {
switch (serialio_value & 0x03) {
// Digital output buffer (ULN2803A) is inverting
case 0: { result = serialio_clearbit; } break;
case 1: { result = serialio_setbit; } break;
case 2: { result = serialio_pollbit; } break;
case 3: { result = serialio_pollchannel; } break;
}
} else {
result = serialio_setchannel;
}
serialio_length = 0;
}
return result;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment