summaryrefslogtreecommitdiff
path: root/software/hhd70dongle
diff options
context:
space:
mode:
authorBernhard Tittelbach <xro@realraum.at>2012-05-17 06:14:33 +0000
committerBernhard Tittelbach <xro@realraum.at>2012-05-17 06:14:33 +0000
commitd8deaecc0cef3db0b57282bb7038cbf59d7a4f77 (patch)
tree710fb48f93adb2b15a3c4cf8fa809fef1f328411 /software/hhd70dongle
parentmake SPI work by understanding how it actually works (diff)
make SPI work by correcting register typo ;-)
git-svn-id: https://svn.spreadspace.org/mur.sat@420 7de4ea59-55d0-425e-a1af-a3118ea81d4c
Diffstat (limited to 'software/hhd70dongle')
-rw-r--r--software/hhd70dongle/c1101lib.c177
-rw-r--r--software/hhd70dongle/c1101lib.h9
-rw-r--r--software/hhd70dongle/hhd70dongle.c18
-rw-r--r--software/hhd70dongle/spi.c54
-rw-r--r--software/hhd70dongle/spi.h1
5 files changed, 152 insertions, 107 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)
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<<DDB0) | (1<<DDB1) | (1<<DDB2);
- SPI_PORT = 0;
+ SPI_PORT = (1<<CS);
SPI_DDR = (1<<MOSI)|(1<<SCK)|(1<<CS);
SPCR = (1<<SPE)|(1<<MSTR); // | (0<<DORD) //select MSB first: DORD == 0
// SPSR = (0<<SPI2X) // f_osc/4
@@ -60,42 +59,35 @@ void spi_init(void)
void spi_cs_enable(void)
{
//pull low
- PORTB &= ~(1<<CS);
+ SPI_PORT &= ~(1<<CS);
}
void spi_cs_disable(void)
{
//pull high
- PORTB |= (1<<CS);
+ SPI_PORT |= (1<<CS);
}
-void spi_write_byte(char byte)
+void spi_c1101_wait_chip_rdy(void)
{
- SPDR = byte; //Load byte to Data register
- while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
+ //c1101 will set MISO to low if ready
+ for (unsigned int c=0; c < 0xFFFFFF && (SPI_PINB_REG & (1<<MISO)); c++);
}
-char spi_read_byte(void)
+void spi_write_byte(char byte)
{
- while(SPI_PINB_REG & (1<<MISO)); /* wait for CC1101 to get ready... */
- return SPSR;
+ SPDR = byte; //Load byte to Data register
+ while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
}
char spi_exchange_byte(char byte)
{
spi_write_byte(byte);
- return spi_read_byte();
+ return SPDR;
}
-//~ void spi_read(unsigned int maxlen, char *data, unsigned int *len)
-//~ {
- //~ PORTB |= (1<<CS);
-
- //~ while(SPI_PINB_REG & (1<<MISO)); /* wait for CC1101 to get ready... */
-
- //~ SPDR = 0x80;
- //~ len = 0;
- //~ while(*len < maxlen && !(SPSR & (1<<SPIF)))
- //~ data[*len++]=SPSR;
- //~ PORTB &= ~(1<<CS);
-//~ }
+char spi_read_byte(void)
+{
+ //transmit something so SCLK runs for 8 bits, so that slave can transfer 1 byte
+ return spi_exchange_byte(0xFF);
+} \ No newline at end of file
diff --git a/software/hhd70dongle/spi.h b/software/hhd70dongle/spi.h
index cc1102b..b4e163d 100644
--- a/software/hhd70dongle/spi.h
+++ b/software/hhd70dongle/spi.h
@@ -36,6 +36,7 @@
void spi_init(void);
void spi_cs_enable(void);
void spi_cs_disable(void);
+void spi_c1101_wait_chip_rdy(void);
void spi_write_byte(char byte);
char spi_read_byte(void);
char spi_exchange_byte(char byte);