diff --git a/firmware/isp.c b/firmware/isp.c index 5e51bf0..9c9b72e 100755 --- a/firmware/isp.c +++ b/firmware/isp.c @@ -140,6 +140,15 @@ void ispDisconnect() { spiHWdisable(); } +void spiInit() { + /* Set MISO output, all others input */ + ISP_DDR = (1 << ISP_MISO); + /* Pull up SS' */ + ISP_OUT = (1 << ISP_RST); + /* Enable SPI, slave mode */ + SPCR = (1 << SPE | 1<< SPIE); +} + uchar ispTransmit_sw(uchar send_byte) { uchar rec_byte = 0; diff --git a/firmware/isp.h b/firmware/isp.h index 2300a58..87f1ed5 100755 --- a/firmware/isp.h +++ b/firmware/isp.h @@ -30,6 +30,9 @@ void ispConnect(); /* Close connection to target device */ void ispDisconnect(); +/* Prepare to listen to target device */ +void spiInit(); + /* read an write a byte from isp using software (slow) */ uchar ispTransmit_sw(uchar send_byte); diff --git a/firmware/main.c b/firmware/main.c index a225432..22c7cea 100755 --- a/firmware/main.c +++ b/firmware/main.c @@ -27,6 +27,14 @@ static uchar replyBuffer[8]; +// choose size to 2^8, so comStart, comEnd can wrap around as ringbuffer +// indexes. +static uchar comBuffer[256]; +static uchar comStart = 0; +static uchar comStop = 0; + +unsigned int blink_counter; + static uchar prog_state = PROG_STATE_IDLE; static uchar prog_sck = USBASP_ISP_SCK_AUTO; @@ -37,6 +45,13 @@ static unsigned int prog_pagesize; static uchar prog_blockflags; static uchar prog_pagecounter; + +ISR(SPI_STC_vect ) +{ + comBuffer[comStop] = SPDR; + comStop ++; +} + uchar usbFunctionSetup(uchar data[8]) { uchar len = 0; @@ -190,6 +205,23 @@ uchar usbFunctionSetup(uchar data[8]) { replyBuffer[2] = 0; replyBuffer[3] = 0; len = 4; + + } else if (data[1] == USBASP_FUNC_SPI_RECVSTART) { + spiInit(); + prog_state = PROG_STATE_SERIAL; + + } else if (data[1] == USBASP_FUNC_SPI_RECVSTOP) { + ledRedOff(); + ispDisconnect(); + prog_state = PROG_STATE_IDLE; + + } else if (data[1] == USBASP_FUNC_SPI_RECV) { + len = 0; + while (comStart != comStop && len < 8) { + replyBuffer[len] = comBuffer[comStart]; + comStart ++; + len ++; + } } usbMsgPtr = replyBuffer; @@ -334,6 +366,12 @@ int main(void) { sei(); for (;;) { usbPoll(); + if (prog_state == PROG_STATE_SERIAL) { + if (--blink_counter == 0) { + toggleLedRed(); + blink_counter = (unsigned int)(1UL << 15); + } + } } return 0; } diff --git a/firmware/usbasp.h b/firmware/usbasp.h index b60bd04..d530dda 100644 --- a/firmware/usbasp.h +++ b/firmware/usbasp.h @@ -30,6 +30,10 @@ #define USBASP_FUNC_TPI_WRITEBLOCK 16 #define USBASP_FUNC_GETCAPABILITIES 127 +#define USBASP_FUNC_SPI_RECVSTART 32 +#define USBASP_FUNC_SPI_RECV 33 +#define USBASP_FUNC_SPI_RECVSTOP 34 + /* USBASP capabilities */ #define USBASP_CAP_0_TPI 0x01 @@ -41,6 +45,7 @@ #define PROG_STATE_WRITEEEPROM 4 #define PROG_STATE_TPI_READ 5 #define PROG_STATE_TPI_WRITE 6 +#define PROG_STATE_SERIAL 7 /* Block mode flags */ #define PROG_BLOCKFLAG_FIRST 1 @@ -67,4 +72,13 @@ #define ledGreenOn() PORTC &= ~(1 << PC0) #define ledGreenOff() PORTC |= (1 << PC0) +#define isLedRedOff() (PORTC & (1 << PC1)) +#define isLedRedOn() ~(isLedRedOff()) +#define isLedGreenOff() (PORTC & (1 << PC0)) +#define isLedGreenOn() ~(isLedGreenOff()) + +#define toggleLedRed() PORTC ^= (1 << PC1) +#define toggleLedGreen() PORTC ^= (1 << PC0) + + #endif /* USBASP_H_ */