diff options
Diffstat (limited to 'firmware/spi.c')
-rw-r--r-- | firmware/spi.c | 190 |
1 files changed, 128 insertions, 62 deletions
diff --git a/firmware/spi.c b/firmware/spi.c index 2b8abb1..b3e3a95 100644 --- a/firmware/spi.c +++ b/firmware/spi.c @@ -36,26 +36,24 @@ #include "spi.h" + void spi_parser(char *buf) { switch(buf[0]) { case CMD_SPI_INIT: - spi_init_usb(); - break; + spi_init_usb(buf[2], buf[3], buf[4]); + break; case CMD_SPI_DEINIT: spi_deinit_usb(); - break; - case CMD_SPI_SPEED: - spi_set_speed_usb((int)buf[2]); - break; + break; case CMD_SPI_SEND: - spi_send_usb(&buf[2], (int)buf[1]); - break; + spi_send_usb(buf[2], &buf[3]); + break; case CMD_SPI_RECV: - spi_receive_usb((int)buf[1]); + spi_receive_usb((int)buf[2]); case CMD_SPI_SEND_AND_RECV: - spi_send_and_receive_usb(&buf[2], (int)buf[1]); - break; + spi_send_and_receive_usb(&buf[3], (int)buf[2]); + break; default: answer[0] = buf[0]; answer[1] = RSP_UNKOWN_CMD; @@ -64,38 +62,111 @@ void spi_parser(char *buf) } } -void spi_init_usb(void) +void spi_init_usb(uint8_t dord, uint8_t mode, uint8_t speed) { answer[0] = CMD_SPI_INIT; - answer[1] = (unsigned char) spi_init(); - answer[3] = 0; + answer[1] = (unsigned char) spi_init(dord, mode, speed); + answer[2] = 0; CommandAnswer(3); } -int spi_init(void) +int spi_init(uint8_t dord, uint8_t mode, uint8_t speed) { - PORTB &= ~((1 << SCK)|(1<<MISO)|(1<<MOSI)); // SCK have to be low in IDLE - DDRB &=~(1 << MISO); - DDRB = (1 << MOSI)|(1 << SCK); + uint8_t cpol, cpha, spr1, spr0, spi2x; + + dord = dord ? 1 : 0; + + switch(mode) + { + case 0: + cpol = 0; + cpha = 0; + break; + case 1: + cpol = 0; + cpha = 1; + break; + case 2: + cpol = 1; + cpha = 0; + break; + case 3: + cpol = 1; + cpha = 1; + break; + default: + return RSP_ERROR; + } - SPCR = 0; - SPSR = 0; + switch(speed) + { + case SPI_SPEED_125kHz: + spi2x = 0; + spr1 = 1; + spr0 = 1; + break; + case SPI_SPEED_250kHz: + spi2x = 0; + spr1 = 1; + spr0 = 0; + break; + case SPI_SPEED_500kHz: + spi2x = 1; + spr1 = 1; + spr0 = 0; + break; + case SPI_SPEED_1MHz: + spi2x = 0; + spr1 = 0; + spr0 = 1; + break; + case SPI_SPEED_2MHz: + spi2x = 1; + spr1 = 0; + spr0 = 1; + break; + case SPI_SPEED_4MHz: + spi2x = 0; + spr1 = 0; + spr0 = 0; + break; + case SPI_SPEED_8MHz: + spi2x = 1; + spr1 = 0; + spr0 = 0; + break; + default: + return RSP_ERROR; + } + + // MOSI, SCK: out/low + // MISO: in + DDRB &= ~(1 << MISO); + DDRB |= (1 << MOSI | 1 << SCK); + PORTB &= ~(1 << MOSI | 1 << MISO | 1 << SCK); // SCK has to be low in IDLE - SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); + // SPE: SPI enable + // DORD: Data Order (0: starting with LSB) + // MSTR: Master mode + // SPR1, SPR2, SPI2X: speed + SPCR = (1 << SPE | dord << DORD | 1 << MSTR | cpol << CPOL | cpha << CPHA | + spr1 << SPR1 | spr0 << SPR0); + SPSR = (spi2x << SPI2X); - octopus.ports[5]=PIN_SCK; - octopus.ports[6]=PIN_MOSI; - octopus.ports[7]=PIN_MISO; + octopus.ports[5] = PIN_SCK; + octopus.ports[6] = PIN_MOSI; + octopus.ports[7] = PIN_MISO; return RSP_OK; } void spi_deinit_usb(void) { - answer[0]=CMD_SPI_DEINIT; - answer[1]=(unsigned char)spi_deinit(); - answer[2]=0; + answer[0] = CMD_SPI_DEINIT; + answer[1] = (unsigned char)spi_deinit(); + answer[2] = 0; + CommandAnswer(3); } @@ -104,36 +175,30 @@ int spi_deinit(void) SPCR = 0; SPSR = 0; - octopus.ports[5]=PIN_OUT; // this is wrong! - octopus.ports[6]=PIN_OUT; // this is wrong! - octopus.ports[7]=PIN_OUT; // this is wrong! + octopus.ports[5] = PIN_NONE; + octopus.ports[6] = PIN_NONE; + octopus.ports[7] = PIN_NONE; return RSP_OK; } -void spi_set_speed_usb(int speed){ - -} - -int spi_set_speed(int speed){ - - return RSP_OK; -} -void spi_send_usb(char * buf, int length) +void spi_send_usb(uint8_t length, char * buf) { - answer[0]=CMD_SPI_SEND; - answer[1]=(unsigned char)spi_send(buf,length); - answer[2]=0; + answer[0] = CMD_SPI_SEND; + answer[1] = (unsigned char)spi_send(length, buf); + answer[2] = 0; + CommandAnswer(3); } -int spi_send(char * buf, int length) +int spi_send(int length, char * buf) { - int i; - for(i=0;i<length;i++){ + uint8_t i; + for(i = 0; i < length; i++) + { SPDR = buf[i]; - while ( !(SPSR & (1 << SPIF)) ) ; + while(!(SPSR & (1 << SPIF))); } return RSP_OK; } @@ -141,22 +206,29 @@ int spi_send(char * buf, int length) void spi_receive_usb(int length) { - answer[0]=CMD_SPI_RECV; - answer[1]=(unsigned char)spi_receive((char*)&answer[2],length); - answer[2]=0; - CommandAnswer(length+2); + answer[0] = CMD_SPI_RECV; + answer[1] = (unsigned char)spi_receive(length, (char*)&answer[2]); + answer[2+length] = 0; + CommandAnswer(3+length); } -unsigned char spi_receive( char * buf, int length) +unsigned char spi_receive(int length, char * buf) { int i; int timeout = 0; - for(i=0;i<length;i++){ + + for(i = 0; i < length; i++) + { SPDR = 0; - while(!(SPSR & (1 << SPIF))) { timeout++; if( timeout > 1000) return RSP_TIMEOUT; } - buf[i]=SPDR; + while(!(SPSR & (1 << SPIF))) + { + if(timeout++ > 1000) + return RSP_TIMEOUT; + } + buf[i] = SPDR; } + return RSP_OK; } @@ -164,8 +236,8 @@ void spi_send_and_receive_usb(char * txbuf, int length) { answer[0]=CMD_SPI_SEND; answer[1]=(unsigned char)spi_send_and_receive(txbuf,(char *)&answer[2],length); - answer[2]=0; - CommandAnswer(2+length); + answer[2+length]=0; + CommandAnswer(3+length); } @@ -180,9 +252,3 @@ int spi_send_and_receive(char * txbuf, char * rxbuf, int length){ } return RSP_OK; } - - - - - - |