diff --git a/documentation/SPI-Proto b/documentation/SPI-Proto index bf19dd5..980ee66 100644 --- a/documentation/SPI-Proto +++ b/documentation/SPI-Proto @@ -8,19 +8,19 @@ Where following values are Valid: |--------------------------------------------------------------------------------------------------------------------------| | Binary Hex Name Address ValueL ValueH Reply Description| |--------------------------------------------------------------------------------------------------------------------------| -| 0000001 0x01 Read-Temp Number of None/Rand None/Rand A 16Bit Value Reads the | +| 0000001 0x01 Read-Temp Number of zeroes/Rand zeroes/Rand A 16Bit Value Reads the | | Thermometer Representing Temperature| | Starting with 0 the Temperature | |--------------------------------------------------------------------------------------------------------------------------| -| 0000002 0x02 Read-Var8 Number of the None/Rand None/Rand A 8Bit Value Reads 8Bit | +| 0000002 0x02 Read-Var8 Number of the zeroes/Rand zeroes/Rand A 8Bit Value Reads 8Bit | | var-DEFINE read from VAR Variable | |--------------------------------------------------------------------------------------------------------------------------| -| 0000003 0x03 Read-Var16 Number of the None/Rand None/Rand A 16Bit Value Reads 16Bit| +| 0000003 0x03 Read-Var16 Number of the zeroes/Rand zeroes/Rand A 16Bit Value Reads 16Bit| | var-DEFINE read from VAR Variable | |--------------------------------------------------------------------------------------------------------------------------| -| 0000004 0x04 Write-Var8 Number of the Value of Var None/Rand None/Rand Writes 8Bit| +| 0000004 0x04 Write-Var8 Number of the Value of Var zeroes/Rand zeroes/Rand Writes 8Bit| | var-DEFINE to write Variable | |--------------------------------------------------------------------------------------------------------------------------| -| 0000005 0x05 Write-Var16 Number of the Value of Var Value of Var None/Rand Writes 16 | +| 0000005 0x05 Write-Var16 Number of the Value of Var Value of Var zeroes/Rand Writes 16 | | var-DEFINE to write (HIGH) to write (LOW) Bit Var | |--------------------------------------------------------------------------------------------------------------------------| diff --git a/firmware/Makefile b/firmware/Makefile index 6a7a846..af8b59d 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -4,9 +4,38 @@ CFLAGS += -std=gnu99 -Wall # implements C99, for # this removes dead code and does global linker optimization #CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax -OBJECTS = usbdrv/usbdrvasm.o usbdrv/usbdrv.o main.o display.o lcd/lcd.o mcp_adc.o i2c_simple.o usb.o +include Makefile.inc +# symbolic targets: +all: master slave -include avrbuild/Makefile.avrbuild +master: + cd masterchip; $(MAKE) $(MFLAGS) +clean-master: + cd masterchip; $(MAKE) $(MFLAGS) clean + +flash-master: + cd masterchip; $(MAKE) $(MFLAGS) flash + +fuses-master: + cd masterchip; $(MAKE) $(MFLAGS) fuses + + +slave: + cd slavechip; $(MAKE) $(MFLAGS) + +clean-slave: + cd slavechip; $(MAKE) $(MFLAGS) clean + +flash-slave: + cd slavechip; $(MAKE) $(MFLAGS) flash + +fuses-slave: + cd slavechip; $(MAKE) $(MFLAGS) fuses + + +clean: + cd masterchip; $(MAKE) $(MFLAGS) clean + cd slavechip; $(MAKE) $(MFLAGS) clean diff --git a/firmware/Makefile.inc b/firmware/Makefile.inc new file mode 100644 index 0000000..03314b8 --- /dev/null +++ b/firmware/Makefile.inc @@ -0,0 +1,13 @@ +DEFINES += -DF_CPU=16000000 +CFLAGS += -save-temps +CFLAGS += -std=gnu99 -Wall # implements C99, for +# this removes dead code and does global linker optimization +#CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax +CFLAGS += -Wall -Os -I. -mmcu=atmega88 + +# further optimization: +#CFLAGS += --param inline-call-cost=2 +CFLAGS += -fno-move-loop-invariants # suggestions from from v-usb +CFLAGS += -fno-tree-scev-cprop +CFLAGS += -fno-inline-small-functions + diff --git a/firmware/i2c_simple.c b/firmware/i2c_simple.c deleted file mode 100644 index f946064..0000000 --- a/firmware/i2c_simple.c +++ /dev/null @@ -1,23 +0,0 @@ - -#include - -#include "i2c_simple.h" - - - -void i2c_init(){ - //TODO: implement -} - -uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data){ - return 0; //TODO: implement -} - -uint8_t i2c_write(uint8_t addr, uint8_t len, uint8_t *data){ - return 0; //TODO: implement -} - -uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t* writedata, uint8_t readlen, - uint8_t* readdata){ - return 0; //TODO: implement -} diff --git a/firmware/masterchip/Makefile b/firmware/masterchip/Makefile new file mode 100644 index 0000000..390b004 --- /dev/null +++ b/firmware/masterchip/Makefile @@ -0,0 +1,67 @@ +# masterchip-makefile +include ../Makefile.inc + +COMPILE = avr-gcc $(CFLAGS) $(DEFINES) + +OBJECTS = usbdrv/usbdrvasm.o usbdrv/usbdrv.o main.o display.o lcd/lcd.o usb.o + +# symbolic targets: +all: firmware.hex + +.c.o: + $(COMPILE) -c $< -o $@ + +.S.o: + $(COMPILE) -x assembler-with-cpp -c $< -o $@ +# "-x assembler-with-cpp" should not be necessary since this is the default +# file type for the .S (with capital S) extension. However, upper case +# characters are not always preserved on Windows. To ensure WinAVR +# compatibility define the file type manually. + +.c.s: + $(COMPILE) -S $< -o $@ + +flash: all + avrdude -c usbasp -p m88 -U flash:w:firmware.hex + +fuses: + avrdude -c usbasp -p m88 -U lfuse:w:0xdf:m -U hfuse:w:0xde:m # external oscillator + + +## what are the source dependencies +%.d: %.c + @set -e; rm -f $@; \ + $(COMPILE) -MM $< | sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' > $@; +# line 1: exits if anything goes wrong +# line 2a: gcc -MM outputs dependencies +# line 2b: insert the %.d into dependency list + +#main.c: version.h + + +clean: + rm -f *.o *.hex *.obj *.i *.s *.d */*.i */*.s */*.o */*.d version.h + +# file targets: +firmware.bin: $(OBJECTS) + $(COMPILE) -o firmware.bin $(OBJECTS) + +firmware.hex: firmware.bin + rm -f firmware.hex firmware.eep.hex + avr-objcopy -j .text -j .data -O ihex firmware.bin firmware.hex + avr-size firmware.bin +# ./checksize firmware.bin 8192 960 +# do the checksize script as our last action to allow successful compilation +# on Windows with WinAVR where the Unix commands will fail. + +disasm: firmware.bin + avr-objdump -d firmware.bin >disasm + +functionsize: disasm + python ../avrbuild/functionsize.py + +countregs: disasm + python ../avrbuild/countregs.py + +# for depends: +-include $(OBJECTS:.o=.d) diff --git a/firmware/display.c b/firmware/masterchip/display.c similarity index 100% rename from firmware/display.c rename to firmware/masterchip/display.c diff --git a/firmware/display.h b/firmware/masterchip/display.h similarity index 100% rename from firmware/display.h rename to firmware/masterchip/display.h diff --git a/firmware/lcd/COPYING b/firmware/masterchip/lcd/COPYING similarity index 100% rename from firmware/lcd/COPYING rename to firmware/masterchip/lcd/COPYING diff --git a/firmware/lcd/lcd.c b/firmware/masterchip/lcd/lcd.c similarity index 100% rename from firmware/lcd/lcd.c rename to firmware/masterchip/lcd/lcd.c diff --git a/firmware/lcd/lcd.h b/firmware/masterchip/lcd/lcd.h similarity index 100% rename from firmware/lcd/lcd.h rename to firmware/masterchip/lcd/lcd.h diff --git a/firmware/main.c b/firmware/masterchip/main.c similarity index 100% rename from firmware/main.c rename to firmware/masterchip/main.c diff --git a/firmware/main.h b/firmware/masterchip/main.h similarity index 97% rename from firmware/main.h rename to firmware/masterchip/main.h index fc9bc6a..0595353 100644 --- a/firmware/main.h +++ b/firmware/masterchip/main.h @@ -26,10 +26,12 @@ #include "spi.h" #include "usb.h" +#define SOFTTIMERNUMS 4 +#include "softtimer.h" + extern uint8_t newThermoData; extern uint16_t thermoData[]; -#define SOFTTIMERNUMS 4 #define LED1PORT PORTC #define LED1APIN 0 diff --git a/firmware/masterchip/softtimer.c b/firmware/masterchip/softtimer.c new file mode 120000 index 0000000..28d64fd --- /dev/null +++ b/firmware/masterchip/softtimer.c @@ -0,0 +1 @@ +../shared/softtimer.c \ No newline at end of file diff --git a/firmware/masterchip/softtimer.h b/firmware/masterchip/softtimer.h new file mode 120000 index 0000000..2d6405e --- /dev/null +++ b/firmware/masterchip/softtimer.h @@ -0,0 +1 @@ +../shared/softtimer.h \ No newline at end of file diff --git a/firmware/masterchip/spi.c b/firmware/masterchip/spi.c new file mode 120000 index 0000000..688c0fb --- /dev/null +++ b/firmware/masterchip/spi.c @@ -0,0 +1 @@ +../shared/spi.c \ No newline at end of file diff --git a/firmware/masterchip/spi.h b/firmware/masterchip/spi.h new file mode 120000 index 0000000..ef58aea --- /dev/null +++ b/firmware/masterchip/spi.h @@ -0,0 +1 @@ +../shared/spi.h \ No newline at end of file diff --git a/firmware/usb.c b/firmware/masterchip/usb.c similarity index 100% rename from firmware/usb.c rename to firmware/masterchip/usb.c diff --git a/firmware/usb.h b/firmware/masterchip/usb.h similarity index 100% rename from firmware/usb.h rename to firmware/masterchip/usb.h diff --git a/firmware/masterchip/usbdrv b/firmware/masterchip/usbdrv new file mode 120000 index 0000000..fe38647 --- /dev/null +++ b/firmware/masterchip/usbdrv @@ -0,0 +1 @@ +../../vusb-20100715/usbdrv \ No newline at end of file diff --git a/firmware/shared/softtimer.c b/firmware/shared/softtimer.c new file mode 100644 index 0000000..2b25429 --- /dev/null +++ b/firmware/shared/softtimer.c @@ -0,0 +1,20 @@ +#include "softtimer.h" + +volatile uint16_t timer1_acc; +uint16_t softtimer_last[SOFTTIMERNUMS]; + +void softtimer_reset(uint8_t timernum){ + softtimer_last[timernum] = timer1_acc; +} + +uint8_t softtimer(uint8_t timernum, uint16_t interval){ + uint16_t timer1_acc_tmp = timer1_acc; // because of volatile + if((uint16_t)(timer1_acc_tmp - (uint16_t)(softtimer_last[timernum]) >= interval )){ + softtimer_last[timernum] = timer1_acc_tmp; + return(1); + } + return(0); +} + +// SOFTTIMER( , ); +// #define SOFTTIMER(n,a) if(softtimer((n),(a*8))) diff --git a/firmware/shared/softtimer.h b/firmware/shared/softtimer.h new file mode 100644 index 0000000..417e61b --- /dev/null +++ b/firmware/shared/softtimer.h @@ -0,0 +1,18 @@ +// NOTES: +// Please #define SOFTTIMERNUMS aNum before including this! + +#ifndef __SOFTTIMER_H +#define __SOFTTIMER_H + +extern volatile uint16_t timer1_acc; +extern uint16_t softtimer_last[SOFTTIMERNUMS]; + + +void softtimer_reset(uint8_t timernum); +uint8_t softtimer(uint8_t timernum, uint16_t interval); + +// SOFTTIMER( , ); +#define SOFTTIMER(n,a) if(softtimer((n),(a*8))) + + +#endif diff --git a/firmware/shared/spi.c b/firmware/shared/spi.c new file mode 100644 index 0000000..870a16d --- /dev/null +++ b/firmware/shared/spi.c @@ -0,0 +1,78 @@ +#include +#include +#include + + +#include + + +/* SPI framework. + * + * currently alpha, uses interrupts, single master/single slave operation + */ + + +uint8_t * volatile spi_writeptr; +uint8_t * volatile spi_readptr; +uint8_t volatile spi_writelen; +uint8_t volatile spi_readlen; +uint8_t spi_readbuf[SPI_READBUF_LEN]; + + +void spi_init(){ + uint8_t spcr, spsr, d; + + /* calculate clock divisor, + * gcc with optimize will do that calculation compile-time. */ + uint8_t spi_clock_divisor(){ + double d; + d = F_CPU / SPI_BAUDRATE; + d = ceil((log(d)/log(2))*0.95); // clock needs dividing by 2^d + // the 0.95 to avoid ceil issues + return d-1; // the -1 because minimum divisor is /2 + } + + d = spi_clock_divisor(); + if(d>7){ + #warning "spi baudrate too slow, cannot be set" + d=7; + } + + //TODO: DDRs setzen + spsr = 0; + spsr |= (d & 1) ? 0 : _BV(SPI2X); + spcr = 0 | _BV(SPIE) | _BV(SPE); + spcr |= (d & 2) ? _BV(SPR0) : 0; + spcr |= (d & 4) ? _BV(SPR1) : 0; + +#ifdef SPI_MASTER + spcr |= _BV(MSTR); +#endif + SPCR = spcr; + SPSR = spsr; + + // initialize interface for ISR: + spi_readptr = spi_readbuf; + spi_readlen = SPI_READBUF_LEN; + spi_writeptr = NULL; +} + +// return true on success, false on error +uint8_t spi_write(uint8_t *data, uint8_t len){ + if(spi_writeptr != NULL){ + return 0 + } + spi_writeptr = data; + spi_writelen = len; + //TODO: handle SS, write out first byte + return 1; +} + +#ifdef SPI_MASTER +ISR(SPI_vector){ + + + + +} +#endif //SPI_MASTER diff --git a/firmware/shared/spi.h b/firmware/shared/spi.h new file mode 100644 index 0000000..bc9969b --- /dev/null +++ b/firmware/shared/spi.h @@ -0,0 +1,6 @@ +#define SPI_BAUDRATE 1000000 +#define SPI_MASTER 1 +#define SPI_READBUF_LEN 32 + +uint8_t spi_write(uint8_t *data, uint8_t len); +void spi_init(); diff --git a/firmware/slavechip/Makefile b/firmware/slavechip/Makefile new file mode 100644 index 0000000..f3fa900 --- /dev/null +++ b/firmware/slavechip/Makefile @@ -0,0 +1,66 @@ +include ../Makefile.inc + +COMPILE = avr-gcc $(CFLAGS) $(DEFINES) + +OBJECTS = main.o mcp_adc.o i2c_simple.o + +# symbolic targets: +all: firmware.hex + +.c.o: + $(COMPILE) -c $< -o $@ + +.S.o: + $(COMPILE) -x assembler-with-cpp -c $< -o $@ +# "-x assembler-with-cpp" should not be necessary since this is the default +# file type for the .S (with capital S) extension. However, upper case +# characters are not always preserved on Windows. To ensure WinAVR +# compatibility define the file type manually. + +.c.s: + $(COMPILE) -S $< -o $@ + +flash: all + avrdude -c usbasp -p m88 -U flash:w:firmware.hex + +fuses: + avrdude -c usbasp -p m88 -U lfuse:w:0xdf:m -U hfuse:w:0xde:m # external oscillator + + +## what are the source dependencies +%.d: %.c + @set -e; rm -f $@; \ + $(COMPILE) -MM $< | sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' > $@; +# line 1: exits if anything goes wrong +# line 2a: gcc -MM outputs dependencies +# line 2b: insert the %.d into dependency list + +#main.c: version.h + + +clean: + rm -f *.o *.hex *.obj *.i *.s *.d */*.i */*.s */*.o */*.d version.h + +# file targets: +firmware.bin: $(OBJECTS) + $(COMPILE) -o firmware.bin $(OBJECTS) + +firmware.hex: firmware.bin + rm -f firmware.hex firmware.eep.hex + avr-objcopy -j .text -j .data -O ihex firmware.bin firmware.hex + avr-size firmware.bin +# ./checksize firmware.bin 8192 960 +# do the checksize script as our last action to allow successful compilation +# on Windows with WinAVR where the Unix commands will fail. + +disasm: firmware.bin + avr-objdump -d firmware.bin >disasm + +functionsize: disasm + python ../avrbuild/functionsize.py + +countregs: disasm + python ../avrbuild/countregs.py + +# for depends: +-include $(OBJECTS:.o=.d) diff --git a/firmware/slavechip/i2c_simple.c b/firmware/slavechip/i2c_simple.c new file mode 100644 index 0000000..1965d49 --- /dev/null +++ b/firmware/slavechip/i2c_simple.c @@ -0,0 +1,97 @@ +#include + +#include "i2c_simple.h" + +void i2c_init() +{ + TWBR = 0;//bit rate + TWSR = 0;//Prescaler + + TWAR = 0x80;//our address 1000 000, don't listen to general call + TWAMR = 0; + + TWCR = TWEA | TWEN;/* TWINT clear -> we must do something; unset TWSTA manually!, TWSTO */ + //TWDR - data +} + +uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data) +{ + TWCR &= ~TWSTO; + TWCR |= TWINT | TWSTA; + while(~TWCR & TWINT) {;}/* get bus access */ + /* no error possible */ + + TWDR = addr | 1; + TWCR &= ~(TWSTA | TWSTO); + TWCR |= TWINT; + while(~TWCR & TWINT) {;}/* transmit address */ + /* possible results: ACK, NAK, abitration lost */ + if(TW_STATUS == TW_MR_SLA_NACK) + { + TWCR |= TWINT | TWSTO; + return 0; + } + else if(TW_STATUS == TW_MR_ARB_LOST) {return 0;} + + uint8_t done = 0; + while(done + 1 < len) + { + TWCR |= TWEA | TWINT;/* send ack after byte */ + while(~TWCR & TWINT) {;}/* read data */ + data[done] = TWDR; + done++; + TWCR |= TWINT; + } + + TWCR &= ~TWEA; + TWCR |= TWINT;/* send nak after byte */ + while(~TWCR & TWINT) {;}/* read data */ + data[done] = TWDR; + done++; + TWCR |= TWINT | TWSTO; + return done; +} + +uint8_t i2c_write(uint8_t addr, uint8_t len, uint8_t *data) +{ + TWCR &= ~TWSTO; + TWCR |= TWINT | TWSTA; + while(~TWCR & TWINT) {;}/* get bus access */ + /* no error possible */ + + TWDR = addr; + TWCR &= ~(TWSTA | TWSTO); + TWCR |= TWINT; + while(~TWCR & TWINT) {;}/* transmit address */ + /* possible results: ACK, NAK, abitration lost */ + if(TW_STATUS == TW_MT_SLA_NACK) + { + TWCR |= TWINT | TWSTO; + return 0; + } + else if(TW_STATUS == TW_MT_ARB_LOST) {return 0;} + + uint8_t done = 0; + while(done < len) + { + TWDR = data[done]; + TWCR |= TWINT; + while(~TWCR & TWINT) {;}/* write data */ + /* possible results: ACK, NAK, abitration lost */ + if(TW_STATUS == TW_MT_DATA_NACK) + { + TWCR |= TWINT | TWSTO; + return done; + } + else if(TW_STATUS == TW_MT_ARB_LOST) {return done;} + done++; + } + + TWCR |= TWINT | TWSTO; + return done; +} + +uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t *writedata, uint8_t readlen, uint8_t *readdata) +{ + return 0; //TODO: implement +} diff --git a/firmware/i2c_simple.h b/firmware/slavechip/i2c_simple.h similarity index 67% rename from firmware/i2c_simple.h rename to firmware/slavechip/i2c_simple.h index c7aee5f..2e76444 100644 --- a/firmware/i2c_simple.h +++ b/firmware/slavechip/i2c_simple.h @@ -1,7 +1,5 @@ - - - - +#ifndef I2C_SIMPLE_H +#define I2C_SIMPLE_H /* initializes i2c interface (master, 400kHz) */ void i2c_init(); @@ -13,5 +11,6 @@ uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data); uint8_t i2c_write(uint8_t addr, uint8_t len, uint8_t *data); /* writes, followed by a repeated start and a read */ -uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t* writedata, uint8_t readlen, - uint8_t* readdata); +uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t *writedata, uint8_t readlen, uint8_t *readdata); + +#endif diff --git a/firmware/slavechip/main.c b/firmware/slavechip/main.c new file mode 100644 index 0000000..55bfe7c --- /dev/null +++ b/firmware/slavechip/main.c @@ -0,0 +1,22 @@ +#include "main.h" +#include "spi.h" + + +void hardinit() { + /* initializes the hardware */ + + sei(); +} + +void softinit() { +} + + +int __attribute__((noreturn)) main(void) { + hardinit(); + softinit(); + + for(;;){ + } +} + diff --git a/firmware/slavechip/main.h b/firmware/slavechip/main.h new file mode 100644 index 0000000..c816a95 --- /dev/null +++ b/firmware/slavechip/main.h @@ -0,0 +1,14 @@ +#ifndef __MAIN_H +#define __MAIN_H +#include +#include +#include +#include +#include +#include +#include +#include + +#define SOFTTIMERNUMS 4 + +#endif //__MAIN_H diff --git a/firmware/mcp_adc.c b/firmware/slavechip/mcp_adc.c similarity index 100% rename from firmware/mcp_adc.c rename to firmware/slavechip/mcp_adc.c diff --git a/firmware/mcp_adc.h b/firmware/slavechip/mcp_adc.h similarity index 100% rename from firmware/mcp_adc.h rename to firmware/slavechip/mcp_adc.h diff --git a/firmware/spi.c b/firmware/slavechip/spi.c similarity index 100% rename from firmware/spi.c rename to firmware/slavechip/spi.c diff --git a/firmware/spi.h b/firmware/slavechip/spi.h similarity index 100% rename from firmware/spi.h rename to firmware/slavechip/spi.h diff --git a/firmware/usbdrv b/firmware/usbdrv deleted file mode 120000 index 421b6b4..0000000 --- a/firmware/usbdrv +++ /dev/null @@ -1 +0,0 @@ -../vusb-20100715/usbdrv/ \ No newline at end of file