summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Tittelbach <xro@realraum.at>2013-02-05 04:02:57 +0000
committerBernhard Tittelbach <xro@realraum.at>2013-02-05 04:02:57 +0000
commitd42183a165f5d5e13b7f0ec4919a45f1bcce98e4 (patch)
tree75cec9a57f72c993e811c4d15b444a6caa8c9cdf
parentupgraded avr utils from spreadspace (diff)
hhd70dongle OOK Beacon Test
git-svn-id: https://svn.spreadspace.org/mur.sat@663 7de4ea59-55d0-425e-a1af-a3118ea81d4c
-rw-r--r--software/hhd70dongle/c1101lib.c193
-rw-r--r--software/hhd70dongle/c1101lib.h11
-rw-r--r--software/hhd70dongle/hhd70.c20
-rw-r--r--software/hhd70dongle/hhd70.h5
-rw-r--r--software/hhd70dongle/hhd70dongle.c68
5 files changed, 240 insertions, 57 deletions
diff --git a/software/hhd70dongle/c1101lib.c b/software/hhd70dongle/c1101lib.c
index 1fbb2fc..cdc1270 100644
--- a/software/hhd70dongle/c1101lib.c
+++ b/software/hhd70dongle/c1101lib.c
@@ -300,6 +300,8 @@ void c1101_init(void)
//AFU Satellite Band: 435.000 - 438.000 kHz
//AFU Salellite Band Max Bandwith: 20 kHz
+
+ hhd70_config_GDO0_OOK_output(false);
}
//Note for comparision:
@@ -343,6 +345,8 @@ void c1101_init_w_rfstudiosettings1(void)
//Values from SmartRFStudio:
c1101_spi_write_patable(pa_table);
+
+ hhd70_config_GDO0_OOK_output(false);
}
@@ -354,7 +358,7 @@ void c1101_init_ook_beacon(void)
// Data format = Synchronous serial mode
// Data rate = 1.00112
// RX filter BW = 58.035714
- // PA ramping = false
+ // PA ramping = true
// Preamble count = 2
// Address config = No address check
// Whitening = false
@@ -367,8 +371,12 @@ void c1101_init_ook_beacon(void)
// Modulation format = ASK/OOK
// Base frequency = 435.199677
// Channel number = 0
- // PA table
- char const pa_table[8] = {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ // PA table by TI
+ //char const pa_table[8] = {0x00,0x12,0x0e,0x34,0x60,0xc5,0xc1,0xc0};
+ // not recommended for OOK even with PA ramping set to false
+ //char const pa_table[8] = {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ // correct PA table for OOK (only first two values matter)
+ char const pa_table[8] = {0x00,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5};
//reset C1101
c1101_spi_strobe_command(SPIC1101_ADDR_SRES);
@@ -380,17 +388,15 @@ void c1101_init_ook_beacon(void)
//
// Rf settings for CC1101
//
- c1101_spi_write_register(SPIC1101_ADDR_IOCFG0, 0x80);
+ c1101_spi_write_register(SPIC1101_ADDR_IOCFG0, 0x00);
//enable RX FIFO interrupt (i.e. GPO2 pulls high if >= FIFOTHR bytes are in RX FIFO)
c1101_spi_write_register(SPIC1101_ADDR_IOCFG2, 0x41 ); //0x40, 0x42, 0x44, 0x47
// pull GPO high (interrupt) if more than 12 bytes in rx buffer (or less than 53 in tx)
-
//c1101_spi_write_register(SPIC1101_ADDR_FIFOTHR,0x47); //RX FIFO and TX FIFO Thresholds
c1101_spi_write_register(SPIC1101_ADDR_FIFOTHR, 0); //assert at 4 bytes in RX Fifo and 61 in TX Fifo
-
//c1101_spi_write_register(SPIC1101_ADDR_PKTCTRL0,0x12);//Packet Automation Control
- c1101_spi_write_register(SPIC1101_ADDR_PKTCTRL0, 0b0000000001); //crc disabled; use FIFOs; variable packet length mode (first TX FIFO byte must be length)
-
+ //c1101_spi_write_register(SPIC1101_ADDR_PKTCTRL0, 0b0000000001); //crc disabled; use FIFOs; variable packet length mode (first TX FIFO byte must be length)
+ c1101_spi_write_register(SPIC1101_ADDR_PKTCTRL0, 0b0000110001); //crc disabled; asynchronous serial input on GDO0
c1101_spi_write_register(SPIC1101_ADDR_FSCTRL1,0x06); //Frequency Synthesizer Control
c1101_spi_write_register(SPIC1101_ADDR_FREQ2,0x10); //Frequency Control Word, High Byte
c1101_spi_write_register(SPIC1101_ADDR_FREQ1,0xBD); //Frequency Control Word, Middle Byte
@@ -403,45 +409,35 @@ void c1101_init_ook_beacon(void)
c1101_spi_write_register(SPIC1101_ADDR_MCSM0,0x18); //Main Radio Control State Machine Configuration
c1101_spi_write_register(SPIC1101_ADDR_FOCCFG,0x16); //Frequency Offset Compensation Configuration
c1101_spi_write_register(SPIC1101_ADDR_WORCTRL,0xFB); //Wake On Radio Control
- c1101_spi_write_register(SPIC1101_ADDR_FREND0,0x11); //Front End TX Configuration
+ c1101_spi_write_register(SPIC1101_ADDR_FREND0,0x11); //Front End TX Configuration // PA_POWER[2:0] = 1
c1101_spi_write_register(SPIC1101_ADDR_FSCAL3,0xE9); //Frequency Synthesizer Calibration
c1101_spi_write_register(SPIC1101_ADDR_FSCAL2,0x2A); //Frequency Synthesizer Calibration
c1101_spi_write_register(SPIC1101_ADDR_FSCAL1,0x00); //Frequency Synthesizer Calibration
c1101_spi_write_register(SPIC1101_ADDR_FSCAL0,0x1F); //Frequency Synthesizer Calibration
c1101_spi_write_patable(pa_table);
+
+ hhd70_config_GDO0_OOK_output(true);
}
-//f_XOSC = 26Mhz
-// freq: desired_carrier_freq [Hz] *2^16 / f_XOSC
-// freq_offset: desired frequency offset [Hz] *2^14 / f_XOSC
-// if_freq: desired intermidiate rx frequency [Hz] *2^10 / f_XOSC
-void c1101_setFrequency(uint32_t freq, uint8_t freq_offset, uint8_t if_freq)
+// see Datasheet Chapter 14.1 Frequency Offset Compensation
+// freq_offset: desired frequency offset [Hz] *2^14 / f_XTAL
+//f_XTAL = 26Mhz
+void c1101_permanently_save_current_rx_tx_freqoffset_auto_compensation()
{
- //make sure we are in idle mode
- char sb=0;
- do
+ int16_t freq_offset;
+ freq_offset = c1101_spi_read_register(SPIC1101_ADDR_FREQUEST);
+ if (freq_offset >= 0)
{
- sb = c1101_getStatus();
- } while (! (SPIC1101_SB_IDLE(sb)));
- //programm frequency
- c1101_spi_write_register(SPIC1101_ADDR_FREQ0, freq & 0xFF);
- c1101_spi_write_register(SPIC1101_ADDR_FREQ1, (freq >> 8) & 0xFF);
- c1101_spi_write_register(SPIC1101_ADDR_FREQ2, (freq >> 16) & 0x3F);
-
- //set frequency offset
- c1101_spi_write_register(SPIC1101_ADDR_FSCTRL0, freq_offset);
- //c1101_spi_write_register(SPIC1101_ADDR_FSCTRL1, if_freq & 0x1F);
-
- //set channel 0
- c1101_spi_write_register(SPIC1101_ADDR_CHANNR, 0);
+ c1101_spi_write_register(SPIC1101_ADDR_FSCTRL0, (uint8_t) freq_offset);
+ }
}
+// WARNING: All content of the PATABLE except for the first byte (index 0) is lost when entering the SLEEP state.
char c1101_putToSleep(void)
{
return c1101_spi_strobe_command(SPIC1101_ADDR_SPWD);
}
-
uint16_t c1101_measureTemp(void)
{
uint16_t temp;
@@ -517,10 +513,124 @@ uint8_t c1101_getNumBytesInTXFifo(void)
return c1101_spi_read_register(SPIC1101_ADDR_TXBYTES);
}
-void c1101_transmitData(char *buffer, uint8_t len)
+
+//true if IDLE state reached before timeout [ms]
+bool c1101_waitUntilIDLEState(uint16_t timeout_ms)
+{
+ uint8_t sb;
+ for (uint16_t c = 0; c < timeout_ms; c++)
+ {
+ sb = c1101_getStatus();
+ if (SPIC1101_SB_IDLE(sb))
+ return true;
+ _delay_ms(1);
+ }
+ return false;
+}
+
+//wait until C1101 left TX State
+bool c1101_waitUntilTXFinished(uint16_t timeout_ms)
+{
+ uint8_t c1101_state;
+ for (uint16_t c = 0; c < timeout_ms; c++)
+ {
+ c1101_state = c1101_getMARCState();
+ c1101_handleMARCStatusByte(c1101_state);
+ _delay_ms(1);
+ if (! (c1101_state == 19 || c1101_state == 20))
+ return true;
+ }
+ return false;
+}
+
+//wait until in IDLE or RX State:
+bool c1101_waitUntilIDLEorRXState(uint16_t timeout_ms)
+{
+ uint8_t c1101_state;
+ for (uint16_t c = 0; c < timeout_ms; c++)
+ {
+ c1101_state = c1101_getMARCState();
+ c1101_handleMARCStatusByte(c1101_state);
+ _delay_ms(1);
+ if (c1101_state == 1 || (c1101_state >= 13 && c1101_state <= 15))
+ return true;
+ }
+ return false;
+}
+
+bool c1101_writeFrequencyRegisters(uint32_t freq)
+{
+ if (! c1101_waitUntilIDLEState(2000)) //wait 2sec max
+ return false;
+ //programm frequency
+ c1101_spi_write_register(SPIC1101_ADDR_FREQ0, freq & 0xFF);
+ c1101_spi_write_register(SPIC1101_ADDR_FREQ1, (freq >> 8) & 0xFF);
+ c1101_spi_write_register(SPIC1101_ADDR_FREQ2, (freq >> 16) & 0x3F);
+
+ //set channel 0
+ c1101_spi_write_register(SPIC1101_ADDR_CHANNR, 0);
+ return true;
+}
+
+uint32_t c1101_readFrequencyRegisters(void)
+{
+ uint32_t freq = 0;
+ freq = ((uint8_t) c1101_spi_read_register(SPIC1101_ADDR_FREQ2)) & 0x3F;
+ freq = freq << 8;
+ freq |= ((uint8_t) c1101_spi_read_register(SPIC1101_ADDR_FREQ1));
+ freq = freq << 8;
+ freq |= ((uint8_t) c1101_spi_read_register(SPIC1101_ADDR_FREQ0));
+ return freq;
+}
+
+//f_XOSC = 26Mhz
+// freq: desired_carrier_freq [Hz] *2^16 / f_XOSC
+bool c1101_setFrequency(uint32_t freq_hz)
+{
+ uint32_t freq = freq_hz / 397;
+ if ( freq <= 0x3FFFFF)
+ return c1101_writeFrequencyRegisters(freq);
+ else
+ return false;
+}
+
+//f_XOSC = 26Mhz
+// freq: desired_carrier_freq [Hz] *2^16 / f_XOSC
+bool c1101_changeFrequencyByRelativeValue(int32_t freq_change_hz)
+{
+ int32_t freq_change = freq_change_hz / 397;
+ int32_t freq = (int32_t) c1101_readFrequencyRegisters();
+
+ freq += freq_change;
+
+ if ( freq >= 0 && freq <= 0x3FFFFF )
+ return c1101_writeFrequencyRegisters((uint32_t) freq);
+ else
+ return false;
+}
+
+uint32_t c1101_getCurrentCarrierFrequencyHz(void)
+{
+ return c1101_readFrequencyRegisters() * 397;
+}
+
+// if_freq: desired intermidiate rx frequency [Hz] *2^10 / f_XOSC
+bool c1101_setIFFrequency(uint32_t freq_hz)
+{
+ uint8_t if_freq = freq_hz / 25391;
+ //make sure we are in idle mode
+ if (! c1101_waitUntilIDLEState(2000)) //wait 2sec max
+ return false;
+
+ c1101_spi_write_register(SPIC1101_ADDR_FSCTRL1, if_freq & 0x1F);
+ return true;
+}
+
+bool c1101_transmitData(char *buffer, uint8_t len)
{
//~ uint8_t debug_sb[6];
uint8_t num_written = 0;
+ bool success = true;
//~ uint8_t mcsm1 = c1101_spi_read_register(SPIC1101_ADDR_MCSM1);
//~ //configure state machine to automatically go to IDLE, once packet was transmitted
//~ mcsm1 = (mcsm1 & 0b11111100) | 0b00;
@@ -557,7 +667,6 @@ void c1101_transmitData(char *buffer, uint8_t len)
hhd70_palna_txmode(); //should actually be done by c1101 itself, by connecting PTT function of GPO0 pin to LNA/PA toggle
//keep buffer filled
- uint8_t c1101_state=0;
do
{
c1101_getStatus();
@@ -566,13 +675,11 @@ void c1101_transmitData(char *buffer, uint8_t len)
len -= num_written;
//wait until in IDLE or RX State:
- do
+ if (! c1101_waitUntilIDLEorRXState(10000)) //wait for max 10s
{
- c1101_state = c1101_getMARCState();
- _delay_ms(100);
- c1101_handleMARCStatusByte(c1101_state);
+ success = false;
+ goto c1101_transmitData_cleanup;
}
- while (!(c1101_state == 1 || (c1101_state >= 13 && c1101_state <= 15)));
//from state IDLE or RX go to TX
num_written = c1101_spi_strobe_command(SPIC1101_ADDR_STX);
@@ -588,17 +695,17 @@ void c1101_transmitData(char *buffer, uint8_t len)
} while (len > 0);
//wait until TX finished
- do
+ if (!c1101_waitUntilTXFinished(10000)) //wait 10s max, then just shut down PA
{
- c1101_state = c1101_getMARCState();
- _delay_ms(100);
- c1101_handleMARCStatusByte(c1101_state);
+ success = false;
+ goto c1101_transmitData_cleanup;
}
- while (c1101_state == 19 || c1101_state == 20);
+ c1101_transmitData_cleanup:
//disable Power Amplifier
//FIXME, instead use PTT function of GPO0 -> interrupt handler -> toggle rx/tx
hhd70_palna_rxmode();
+ return success;
}
void c1101_transmitData_infPktMode(char *buffer, uint8_t len)
diff --git a/software/hhd70dongle/c1101lib.h b/software/hhd70dongle/c1101lib.h
index 1742bdd..8bd80ae 100644
--- a/software/hhd70dongle/c1101lib.h
+++ b/software/hhd70dongle/c1101lib.h
@@ -34,6 +34,8 @@
#define C1101_FIFO_MAX_LEN 64
+#include <stdbool.h>
+
//read/write config registers:
#define SPIC1101_ADDR_IOCFG2 0x00
#define SPIC1101_ADDR_IOCFG1 0x01
@@ -147,9 +149,12 @@ void c1101_handleStatusByte(char sb);
char c1101_getStatus(void);
uint16_t c1101_measureTemp(void);
void c1101_spi_dump_registers_to_usb(void);
-void c1101_setFrequency(uint32_t freq, uint8_t freq_offset, uint8_t if_freq);
-
-void c1101_transmitData(char *buffer, uint8_t len);
+void c1101_permanently_save_current_rx_tx_freqoffset_auto_compensation(void);
+bool c1101_setFrequency(uint32_t freq_hz);
+bool c1101_changeFrequencyByRelativeValue(int32_t freq_change_hz);
+uint32_t c1101_getCurrentCarrierFrequencyHz(void);
+bool c1101_setIFFrequency(uint32_t freq_hz);
+bool c1101_transmitData(char *buffer, uint8_t len);
void c1101_transmitData_infPktMode(char *buffer, uint8_t len);
void c1101_recieveData(void);
diff --git a/software/hhd70dongle/hhd70.c b/software/hhd70dongle/hhd70.c
index 0abe61d..e8c973b 100644
--- a/software/hhd70dongle/hhd70.c
+++ b/software/hhd70dongle/hhd70.c
@@ -44,6 +44,26 @@ void hhd70_init(void)
// SPSR = (1<<SPI2X); (4MHz vs. 8MHz)
}
+void hhd70_config_GDO0_OOK_output(bool output_mode)
+{
+ hhd70_set_OOK_GDO0_low();
+ if (output_mode)
+ SPI_DDR |= (1 << GDO0);
+ else
+ SPI_DDR &= ~(1 << GDO0);
+}
+
+void hhd70_set_OOK_GDO0_high(void)
+{
+ SPI_PORT |= (1 << GDO0);
+}
+
+void hhd70_set_OOK_GDO0_low(void)
+{
+ //pull low
+ SPI_PORT &= ~(1<<GDO0);
+}
+
void hhd70_spi_cs_enable(void)
{
//pull low
diff --git a/software/hhd70dongle/hhd70.h b/software/hhd70dongle/hhd70.h
index c5b001f..e8a4fa0 100644
--- a/software/hhd70dongle/hhd70.h
+++ b/software/hhd70dongle/hhd70.h
@@ -33,6 +33,8 @@
#ifndef MURSAT_hhd70_h_INCLUDED
#define MURSAT_hhd70_h_INCLUDED
+#include <stdbool.h>
+
#define SPI_DDR DDRB
#define SPI_PORT PORTB
#define SPI_PINB_REG PINB
@@ -61,5 +63,8 @@ void hhd70_palna_txmode(void);
void hhd70_palna_rxmode(void);
void hhd70_palna_off(void);
int8_t hhd70_rx_data_available(void);
+void hhd70_config_GDO0_OOK_output(bool output_mode);
+void hhd70_set_OOK_GDO0_high(void);
+void hhd70_set_OOK_GDO0_low(void);
#endif
diff --git a/software/hhd70dongle/hhd70dongle.c b/software/hhd70dongle/hhd70dongle.c
index d031a4a..34635a4 100644
--- a/software/hhd70dongle/hhd70dongle.c
+++ b/software/hhd70dongle/hhd70dongle.c
@@ -167,11 +167,12 @@ int main(void)
enable_beacon_part=false;
int8_t fdev_m = 1;
int8_t fdev_e = 1;
+ uint32_t prev_ook_freq = c1101_getCurrentCarrierFrequencyHz();
- char mursat_beacon[256];
- for(int i=0;i<sizeof(mursat_beacon);++i) {
- mursat_beacon[i] = 0xFF;
- }
+ //char mursat_beacon[256];
+ //for(int i=0;i<sizeof(mursat_beacon);++i) {
+ // mursat_beacon[i] = 0xFF;
+ //}
for(;;)
{
@@ -196,10 +197,6 @@ int main(void)
enable_rx_part=false;
enable_tx_part=false;
c1101_init_ook_beacon();
- hhd70_palna_txmode();
- }
- else {
- hhd70_palna_rxmode();
}
print_part_status();
}
@@ -252,6 +249,47 @@ int main(void)
fdev_m %= 8;
}
}
+ else if ((char) recv_byte == '+' || (char) recv_byte == '-' || (char) recv_byte == '#' || (char) recv_byte == '_' || (char) recv_byte == ':' || (char) recv_byte == '.' || (char) recv_byte == 'f'|| (char) recv_byte == '?')
+ {
+ int32_t change_freq = 0;
+ switch (recv_byte)
+ {
+ case '+':
+ change_freq = 1000000;
+ break;
+ case '-':
+ change_freq = -1000000;
+ break;
+ case '#':
+ change_freq = 10000000;
+ break;
+ case '_':
+ change_freq = -10000000;
+ break;
+ case ':':
+ change_freq = 100000;
+ break;
+ case '.':
+ change_freq = -100000;
+ break;
+ case 'f':
+ CDC_Device_SendString(&VirtualSerial_CDC_Interface, "Setting Frequency to previously adjusted value.\r\n");
+ c1101_setFrequency(prev_ook_freq);
+ break;
+ case '?':
+ //just show current frequency
+ break;
+ }
+ if (change_freq != 0)
+ {
+ sprintf(write_buffer,"Frequency %s by %lu KHz\r\n", (change_freq > 0 ? "up" : "down"), (change_freq > 0 ? 1 : -1) * change_freq / 1000);
+ CDC_Device_SendString(&VirtualSerial_CDC_Interface, write_buffer);
+ c1101_changeFrequencyByRelativeValue(change_freq);
+ prev_ook_freq = c1101_getCurrentCarrierFrequencyHz();
+ }
+ sprintf(write_buffer,"Frequency is now: %lu Hz\r\n", c1101_getCurrentCarrierFrequencyHz());
+ CDC_Device_SendString(&VirtualSerial_CDC_Interface, write_buffer);
+ }
}
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
@@ -339,11 +377,19 @@ int main(void)
if (enable_beacon_part)
{
-// char mursat_beacon[8] = {0b11101110, 0b11100010, 0b00111010, 0b10101000, 0b10001110, 0b11101110, 0b00101011, 0b10100000}; //OE6EOF
- led_on();
+ //char mursat_beacon[8] = {0b11101110, 0b11100010, 0b00111010, 0b10101000, 0b10001110, 0b11101110, 0b00101011, 0b10100000}; //OE6EOF
CDC_Device_SendString(&VirtualSerial_CDC_Interface,"OOK Sending Beacon\r\n");
- c1101_transmitData_infPktMode(mursat_beacon,sizeof(mursat_beacon));
+ led_on();
+ //c1101_transmitData_infPktMode(mursat_beacon,sizeof(mursat_beacon));
+ hhd70_palna_txmode();
+ c1101_spi_strobe_command(SPIC1101_ADDR_STX);
+ hhd70_set_OOK_GDO0_high();
+ _delay_ms(1000);
led_off();
+ hhd70_set_OOK_GDO0_low();
+ c1101_spi_strobe_command(SPIC1101_ADDR_SIDLE);
+ hhd70_palna_rxmode();
+ _delay_ms(200);
}
}
}