diff options
Diffstat (limited to 'software/hhd70dongle/c1101lib.c')
-rw-r--r-- | software/hhd70dongle/c1101lib.c | 177 |
1 files changed, 104 insertions, 73 deletions
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) |