From d8deaecc0cef3db0b57282bb7038cbf59d7a4f77 Mon Sep 17 00:00:00 2001 From: Bernhard Tittelbach Date: Thu, 17 May 2012 06:14:33 +0000 Subject: make SPI work by correcting register typo ;-) git-svn-id: https://svn.spreadspace.org/mur.sat@420 7de4ea59-55d0-425e-a1af-a3118ea81d4c --- software/hhd70dongle/c1101lib.c | 177 ++++++++++++++++++++++--------------- software/hhd70dongle/c1101lib.h | 9 +- software/hhd70dongle/hhd70dongle.c | 18 +++- software/hhd70dongle/spi.c | 54 +++++------ software/hhd70dongle/spi.h | 1 + 5 files changed, 152 insertions(+), 107 deletions(-) (limited to 'software') diff --git a/software/hhd70dongle/c1101lib.c b/software/hhd70dongle/c1101lib.c index cda199b..57ee7eb 100644 --- a/software/hhd70dongle/c1101lib.c +++ b/software/hhd70dongle/c1101lib.c @@ -39,93 +39,91 @@ /**** Helper Functions ****/ -#define SPIC1101_MAX_WAIT 1024 -#define SPIC1101_SEND_MOSTLY_HARMLESS 0 +#define SPIC1101_MAX_WAIT 21 -unsigned int attempts = 0; -char spi_c1101_exchange(char *data, int len) +int16_t spi_c1101_write_byte_ok_get_status(char data) { - char sb; uint8_t debug_sb[6]; - char rbyte; - spi_cs_enable(); - attempts = 0; - while (len-- > 0) + char sb; + unsigned int attempts = 0; + do { - //~ while ( ! (SPIC1101_SB_CHIPRDY(spi_read_byte()))); - sb = spi_exchange_byte(*data); - usb_rawhid_send((uint8_t*)"spi byte written",255); + sb = spi_exchange_byte(data); + usb_rawhid_send((uint8_t*)"spi byte exchanged ",255); debug_sprint_int16hex(debug_sb, sb); - usb_rawhid_send(debug_sb,255); - while ( ! (SPIC1101_SB_CHIPRDY(sb))); - { - usb_rawhid_send((uint8_t*)"not yet chipready",255); - sb = spi_exchange_byte(*data); - debug_sprint_int16hex(debug_sb, sb); - usb_rawhid_send(debug_sb,255); - if (attempts++ > SPIC1101_MAX_WAIT) - return -1; - } - usb_rawhid_send((uint8_t*)"spi chipready",255); - data++; - } - rbyte = spi_exchange_byte(SPIC1101_SEND_MOSTLY_HARMLESS); - usb_rawhid_send((uint8_t*)"spi byte read",255); - spi_cs_disable(); - return rbyte; + usb_rawhid_send(debug_sb,255); + if (attempts++ > SPIC1101_MAX_WAIT) + return -1; + } while ( SPIC1101_SB_CHIPRDY(sb) == 0 ); + return sb; } // note addresses range from 0x00 to 0x2F for normal registers and 0xF0 to 0xFD for special status registers -char spi_c1101_read_register(char address) +int16_t spi_c1101_read_register(char address) { - char data[1]; - data[0]=address | 0x80; - return spi_c1101_exchange(data, 1); + char rbyte; + if (address < 0x30) + address |= 0x80; + else + address |= 0xC0; + spi_cs_enable(); + spi_c1101_wait_chip_rdy(); + if (spi_c1101_write_byte_ok_get_status(address) < 0) + return -1; + _delay_ms(10); //FIXME: propably don't need this + rbyte = spi_read_byte(); + uint8_t debug_sb[6]; + debug_sprint_int16hex(debug_sb, rbyte); + usb_rawhid_send(debug_sb,255); + rbyte = spi_read_byte(); + debug_sprint_int16hex(debug_sb, rbyte); + usb_rawhid_send(debug_sb,255); + rbyte = spi_read_byte(); + debug_sprint_int16hex(debug_sb, rbyte); + usb_rawhid_send(debug_sb,255); + spi_cs_disable(); + return rbyte; } // note addresses range from 0x00 to 0x2F for normal registers -char spi_c1101_write_register(char address, char byte) +int16_t spi_c1101_write_register(char address, char byte) { - char data[2]; - data[0]=address & 0x2F; - data[1]=byte; - return spi_c1101_exchange(data, 2); + spi_cs_enable(); + spi_c1101_wait_chip_rdy(); + if (spi_c1101_write_byte_ok_get_status(address & 0x2F) < 0) + return -1; + _delay_ms(2); + if (spi_c1101_write_byte_ok_get_status(byte) < 0) + return -1; + spi_cs_disable(); + return 1; } // note addresses range from 0x30 to 0x3D for command strobes -char spi_c1101_strobe_command(char address) +int16_t spi_c1101_strobe_command(char address) { - char data[1]; - data[0]=address; - return spi_c1101_exchange(data, 1); + if (spi_c1101_write_byte_ok_get_status(address) < 0) + return -1; + return 1; } int spi_c1101_read_rxfifo(int leave_num_bytes, char *buffer, int maxlen) { - char sb; - uint8_t debug_sb[6]; - attempts = 0; + int16_t sb; int num_read = 0; int num_fifo_available = 0; spi_cs_enable(); - sb = spi_exchange_byte(SPIC1101_ADDR_FIFO_READ_BURST); - while ( ! (SPIC1101_SB_CHIPRDY(sb))); - { - usb_rawhid_send((uint8_t*)"not yet chipready",255); - sb = spi_exchange_byte(SPIC1101_ADDR_FIFO_READ_BURST); - debug_sprint_int16hex(debug_sb, sb); - usb_rawhid_send(debug_sb,255); - if (attempts++ > SPIC1101_MAX_WAIT) - return -1; - } - usb_rawhid_send((uint8_t*)"spi chipready",255); - num_fifo_available = SPIC1101_SB_FIFO_BYTES_AVAILABLE(sb); + spi_c1101_wait_chip_rdy(); + sb = spi_c1101_write_byte_ok_get_status(SPIC1101_ADDR_FIFO_READ_BURST); + if (sb < 0) + return -1; + num_fifo_available = SPIC1101_SB_FIFO_BYTES_AVAILABLE((char)sb); //note if num_fifo_available == 15 then 15 or more bytes are available //FIXTHIS while (maxlen-- && num_fifo_available - num_read <= leave_num_bytes) { //hope this works !! - buffer[num_read++] = spi_exchange_byte(SPIC1101_SEND_MOSTLY_HARMLESS); + buffer[num_read++] = spi_read_byte(); } spi_cs_disable(); return num_read; @@ -135,28 +133,18 @@ int spi_c1101_read_rxfifo(int leave_num_bytes, char *buffer, int maxlen) int spi_c1101_write_txfifo(char *buffer, int len) { char sb; - uint8_t debug_sb[6]; - attempts = 0; int num_written = 0; int num_fifo_available = 0; spi_cs_enable(); - sb = spi_exchange_byte(SPIC1101_ADDR_FIFO_WRITE_BURST); - while ( ! (SPIC1101_SB_CHIPRDY(sb))); - { - usb_rawhid_send((uint8_t*)"not yet chipready",255); - sb = spi_exchange_byte(SPIC1101_ADDR_FIFO_WRITE_BURST); - debug_sprint_int16hex(debug_sb, sb); - usb_rawhid_send(debug_sb,255); - if (attempts++ > SPIC1101_MAX_WAIT) - return -1; - } - usb_rawhid_send((uint8_t*)"spi chipready",255); - num_fifo_available = SPIC1101_SB_FIFO_BYTES_AVAILABLE(sb); + spi_c1101_wait_chip_rdy(); + sb = spi_c1101_write_byte_ok_get_status(SPIC1101_ADDR_FIFO_WRITE_BURST); + if (sb < 0) + return -1; + num_fifo_available = SPIC1101_SB_FIFO_BYTES_AVAILABLE((char)sb); //note if num_fifo_available == 15 then 15 or more bytes are available //FIXTHIS if (num_fifo_available < len) len = num_fifo_available; - while (len--) { //hope this works !! @@ -170,6 +158,16 @@ int spi_c1101_write_txfifo(char *buffer, int len) /**** External Functions ****/ +void c1101_init(void) +{ + //reset C1101 + spi_c1101_strobe_command(SPIC1101_ADDR_SRES); + _delay_ms(100); + //flush FIFOs + spi_c1101_strobe_command(SPIC1101_ADDR_SFRX); + spi_c1101_strobe_command(SPIC1101_ADDR_SFTX); + c1101_getStatus(); +} char c1101_getVersion(void) { @@ -181,6 +179,39 @@ char c1101_getPartNum(void) return spi_c1101_read_register(SPIC1101_ADDR_PARTNUM); } +void c1101_handleStatusByte(char sb) +{ + //on RXFifo Overflow, Flush RX Fifo + if (SPIC1101_SB_RXFIFO_OVERFLOW(sb)) + { + spi_c1101_strobe_command(SPIC1101_ADDR_SFRX); + usb_rawhid_send((uint8_t*)"RX fifo flushed",255); + } + //on TXFifo Overflow, Flush TX Fifo + if (SPIC1101_SB_TXFIFO_OVERFLOW(sb)) + { + spi_c1101_strobe_command(SPIC1101_ADDR_SFTX); + usb_rawhid_send((uint8_t*)"TX fifo flushed",255); + } +} + +char c1101_getStatus(void) +{ + char sb=0; + spi_cs_enable(); + spi_c1101_wait_chip_rdy(); + sb = spi_c1101_write_byte_ok_get_status(SPIC1101_ADDR_SNOP); + spi_cs_disable(); + //debug start + uint8_t debug_sb[6]; + usb_rawhid_send((uint8_t*)"c1101 status:",255); + debug_sprint_int16hex(debug_sb, sb); + usb_rawhid_send(debug_sb,255); + //debug end + c1101_handleStatusByte(sb); + return sb; +} + //max len: 64 bytes void c1101_writeTXFifo(char *buffer, unsigned int len) diff --git a/software/hhd70dongle/c1101lib.h b/software/hhd70dongle/c1101lib.h index 64cf876..43cfc2b 100644 --- a/software/hhd70dongle/c1101lib.h +++ b/software/hhd70dongle/c1101lib.h @@ -119,7 +119,7 @@ #define SPIC1101_ADDR_FIFO_WRITE 0x3F #define SPIC1101_ADDR_FIFO_WRITE_BURST (0x3F | 0x40) -#define SPIC1101_SB_CHIPRDY(x) x & 0b10000000 +#define SPIC1101_SB_CHIPRDY(x) (x & 0b10000000) #define SPIC1101_SB_IDLE(x) (x & 0b01110000) == 0 #define SPIC1101_SB_RXMODE(x) (x & 0b01110000) == 0b0010000 #define SPIC1101_SB_TXMODE(x) (x & 0b01110000) == 0b0100000 @@ -131,9 +131,16 @@ #define SPIC1101_SB_FIFO_BYTES_AVAILABLE(x) (x & 0b00001111) +int16_t spi_c1101_read_register(char address); +int16_t spi_c1101_write_register(char address, char byte); + +void c1101_init(void); char c1101_getVersion(void); char c1101_getPartNum(void); +void c1101_handleStatusByte(char sb); +char c1101_getStatus(void); + //max len: 64 bytes void c1101_writeTXFifo(char *buffer, unsigned int len); diff --git a/software/hhd70dongle/hhd70dongle.c b/software/hhd70dongle/hhd70dongle.c index 3d7fa95..c221ffc 100644 --- a/software/hhd70dongle/hhd70dongle.c +++ b/software/hhd70dongle/hhd70dongle.c @@ -47,9 +47,10 @@ uint8_t read_buffer[64]; // buffer for reading usb signals uint8_t write_buffer[64]; // buffer for writing usb signals //TODOs: +// * remove code duplications +// * speed up and simplify code // * make as much use of sleep modes as possible // * use adc noise canceler (i.e. automatic sampling during cpu sleep) -// * define and listen for an usb_hid reset command -> jump to bootload address // * read atmega temp // * safely save state in eeprom (2 memory regions, only use the one with the "written successfully bit" which is written last) @@ -67,7 +68,9 @@ int main(void) //usb_rawhid_send(write_buffer, 23); usb_rawhid_send((uint8_t*)"hhd70dongle ready",17); - + + c1101_init(); + for(;;) { _delay_ms(250); @@ -90,6 +93,17 @@ int main(void) usb_rawhid_send((uint8_t*)"c1101 version:",255); debug_sprint_int16hex(write_buffer, c1101_getVersion()); usb_rawhid_send(write_buffer,255); + _delay_ms(250); + usb_rawhid_send((uint8_t*)"c1101 freq0:",255); + debug_sprint_int16hex(write_buffer, spi_c1101_read_register(SPIC1101_ADDR_FREQ0)); + usb_rawhid_send(write_buffer,255); + usb_rawhid_send((uint8_t*)"c1101 freq1:",255); + debug_sprint_int16hex(write_buffer, spi_c1101_read_register(SPIC1101_ADDR_FREQ1)); + usb_rawhid_send(write_buffer,255); + usb_rawhid_send((uint8_t*)"c1101 freq2:",255); + debug_sprint_int16hex(write_buffer, spi_c1101_read_register(SPIC1101_ADDR_FREQ2)); + usb_rawhid_send(write_buffer,255); + //~ char buf[10]; //~ unsigned int len; //~ spi_read(sizeof(buf),buf,&len); diff --git a/software/hhd70dongle/spi.c b/software/hhd70dongle/spi.c index 85831d1..a2d9c55 100644 --- a/software/hhd70dongle/spi.c +++ b/software/hhd70dongle/spi.c @@ -36,20 +36,19 @@ #define SPI_DDR DDRB #define SPI_PORT PORTB #define SPI_PINB_REG PINB -#define CS 0 -#define SCK 1 -#define MOSI 2 -#define MISO 3 -#define GDO2 4 -#define GDO0 5 -#define RE 6 -#define TE 7 +#define CS DDB0 +#define SCK DDB1 +#define MOSI DDB2 +#define MISO DDB3 +#define GDO2 DDB4 +#define GDO0 DDB5 +#define RE DDB6 +#define TE DDB7 void spi_init(void) { //configure Direction of SS / PB0 , MOSI and SCLK as Output to drive CS of CC1101 - DDRB = (1<