From 4d0f5b8b157443db6d0a2298b1f572d05d342a43 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 20 May 2012 11:10:25 +0200 Subject: [PATCH] Add the capability to read out a buffer at the USBasp. This buffer should be filled by target device. As the USBasp is slave at USB side, it should also be slave at the SPI side, so it can handle the buffering well. --- firmware/isp.c | 9 +++++++++ firmware/isp.h | 3 +++ firmware/main.c | 38 ++++++++++++++++++++++++++++++++++++++ firmware/usbasp.h | 14 ++++++++++++++ 4 files changed, 64 insertions(+) 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_ */