Skip to content

Commit

Permalink
+ track node firmware
Browse files Browse the repository at this point in the history
  • Loading branch information
soeren committed Jun 16, 2012
1 parent 23c6345 commit 8cd5a85
Show file tree
Hide file tree
Showing 3 changed files with 248 additions and 0 deletions.
86 changes: 86 additions & 0 deletions locodoco/firmware/track_node/Makefile
@@ -0,0 +1,86 @@
OBJ = main.o

# hardware revision (only v1 yet)
HWREF := 1

# Default values
MCU_TARGET ?= attiny45
OUT ?= track-node-hwr$(HWREF)-$(MCU_TARGET)
MCU_CC ?= avr-gcc
MCU_AS ?= avr-as
OPTIMIZE ?= -Os
WARNINGS ?= -Wall -Winline
DEFS ?= -DF_CPU=8000000 -DHWREF=$(HWREF) -DMCU=$(MCU_TARGET)
CFLAGS += -mmcu=$(MCU_TARGET) $(OPTIMIZE) $(WARNINGS) $(DEFS) -I.
ASFLAGS += -mmcu=avr5
LDFLAGS = -Wl,-Map,$(OUT).map

# External Tools
OBJCOPY ?= avr-objcopy
OBJDUMP ?= avr-objdump
FLASHCMD ?= avrdude -c usbasp -p $(MCU_TARGET) -U flash:w:$(OUT).hex
ERASECMD ?= avrdude -c usbasp -p $(MCU_TARGET) -e

#############################################################################
# Rules
all: $(OUT).elf lst text eeprom

clean:
rm -rf $(OUT) *.o *.lst *.map *.hex *.bin *.srec
rm -rf *.srec $(OUT).elf

flash: $(OUT).hex
$(ERASECMD)
$(FLASHCMD)



#############################################################################
# Building Rules
$(OUT).elf: $(OBJ)
$(MCU_CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)

%.o: %.c
$(MCU_CC) $(CFLAGS) -c $< -o $@

%.o: %.S
$(MCU_AS) $(ASFLAGS) -o $@ $<

lst: $(OUT).lst

%.lst: %.elf
$(OBJDUMP) -h -S $< > $@

# Rules for building the .text rom images
text: hex bin srec

hex: $(OUT).hex
bin: $(OUT).bin
srec: $(OUT).srec

%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@

%.srec: %.elf
$(OBJCOPY) -j .text -j .data -O srec $< $@

%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@

# Rules for building the .eeprom rom images

eeprom: ehex ebin esrec

ehex: $(OUT)_eeprom.hex
ebin: $(OUT)_eeprom.bin
esrec: $(OUT)_eeprom.srec

%_eeprom.hex: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@

%_eeprom.srec: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@

%_eeprom.bin: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@

60 changes: 60 additions & 0 deletions locodoco/firmware/track_node/config.h
@@ -0,0 +1,60 @@
#include <avr/io.h>
#include <avr/interrupt.h>

#pragma once

#if \
defined(__AVR_ATtiny13__) || \
defined(__AVR_ATtiny13A__)
/*
tiny13 support *NOT TESTED YET*
*/
#error wtf
#define TIMER_INIT \
TCCR0A = _BV(WGM1); /* clear on compare match */ \
OCRA = 125; /* 4.8M / 38400 -> 125 cycles/bit */ \
TCCR0B = (_BV(CS00)); /* clk/1; */ \
TIMSK0 = _BV(OCIE0A) /* OCR0A int */

#define BIT_ISR ISR(TIMER0_COMPA_vect)

#define PIN_LED0 _BV(PB0)
#define DDR_LED0 DDRB
#define PORT_LED0 PORTB

#define PRESCALER_INIT /* system clock prescaler */ \
CLKPR = _BV(CLKPCE); \
CLKPR = _BV(CLKPS0) /* /2 */

#elif \
defined(__AVR_ATtiny25__) || \
defined(__AVR_ATtiny45__) || \
defined(__AVR_ATtiny85__)

#define TIMER_INIT \
TCCR0A = _BV(WGM01); /* clear on compare match */ \
OCR0A = 52; /* 2M / 38400 -> 52.083 cycles/bit */ \
TCCR0B = (_BV(CS00)); /* clk/1; */ \
TIMSK = _BV(OCIE0A) /* OCR0A int */

#define BIT_ISR ISR(TIMER0_COMPA_vect)

#define PIN_LED0 _BV(PB0)
#define DDR_LED0 DDRB
#define PORT_LED0 PORTB

#define PRESCALER_INIT /* system clock prescaler */ \
CLKPR = _BV(CLKPCE); \
CLKPR = _BV(CLKPS1) /* / 4 */
#else
#error "can't find valid config for your mcu. please edit config.h"
#endif

/* general config */

#define OUT0_0 PORT_LED0 &= ~(PIN_LED0)
#define OUT0_1 PORT_LED0 |= PIN_LED0
#define OUT0_INIT DDR_LED0 |= PIN_LED0

/* additional stop bits at the end of each transmission */
#define NUM_STOPBITS 8
102 changes: 102 additions & 0 deletions locodoco/firmware/track_node/main.c
@@ -0,0 +1,102 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <util/crc16.h>

#include "config.h"

volatile static uint8_t tx_seq[16];
volatile static uint8_t num_bytes = 0;

BIT_ISR
{
static uint8_t bytec = 0;
static uint8_t mask = 0xff;

if (!mask) /* stop bit(s) */
{

if (bytec < num_bytes)
{
mask = 0xff; /* start bit */
asm volatile("nop"); /* shortest code path - add some nops */
asm volatile("nop");
OUT0_1;
return;
}

OUT0_1; /* intentionally twice to make delays close to symmetric */

/* send extra stop bits at the end of the transmission */
if (bytec < num_bytes + NUM_STOPBITS)
return;

/* start over */
mask = 0xff;
bytec = 0;
} else if (mask == 0xff) /* start bit */
{
bytec++;
mask = 0x80;
OUT0_0;
} else /* data bits */
{
if (tx_seq[bytec] & mask)
{
OUT0_1;
} else
{
OUT0_0;
}
mask >>= 1;
}
}

/* read eeprom, fill tx_seq
*/
void eeprom_init()
{
uint16_t *crcptr;
uint8_t i;

eeprom_busy_wait();
num_bytes = eeprom_read_byte ((const void*) 0x00);

if (num_bytes > sizeof(tx_seq) - 2)
{
num_bytes = sizeof (tx_seq) - 2;
tx_seq[0] = 'E';
tx_seq[1] = 'S';
tx_seq[2] = 'I';
tx_seq[3] = 'Z';
tx_seq[4] = 'E';
return; /* unprogrammed */
}
eeprom_busy_wait();
eeprom_read_block ((void*) &tx_seq[0], (const void*) 0x01, num_bytes);

/* calc & gen crc */
crcptr = (uint16_t *) &tx_seq[num_bytes];
*crcptr = 0x00;

for (i=0;i<num_bytes;i++)
{
*crcptr = _crc16_update (*crcptr, tx_seq[i]);
}

num_bytes += 2;
}

int main ()
{
eeprom_init();
PRESCALER_INIT;
OUT0_INIT;
TIMER_INIT;
sei();

while (23)
{

}
}

0 comments on commit 8cd5a85

Please sign in to comment.