IQ modulation on sx126x

Dependencies:   sx126x

Revision:
1:061c7250788a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jul 24 17:08:26 2018 -0700
@@ -0,0 +1,338 @@
+#include "sx12xx.h"
+
+RawSerial pc(USBTX, USBRX);
+
+#ifdef TARGET_FF_ARDUINO
+    SPI spi(D11, D12, D13); // mosi, miso, sclk
+                   //spi, nss, busy, dio1
+    SX126x radio(spi, D7, D3, D5);
+ 
+    DigitalOut antswPower(D8);
+    AnalogIn xtalSel(A3);
+ 
+    DigitalIn chipType(A2);
+ 
+    #define PINNAME_NRST            A0
+ 
+    #define LED_ON      1
+    #define LED_OFF     0
+    DigitalOut tx_led(A4);
+    DigitalOut rx_led(A5);
+ 
+    void chipModeChange()
+    {
+        if (radio.chipMode == CHIPMODE_NONE) {
+            tx_led = LED_OFF;
+            rx_led = LED_OFF;
+        } else if (radio.chipMode == CHIPMODE_TX) {
+            tx_led = LED_ON;
+            rx_led = LED_OFF;
+        } else if (radio.chipMode == CHIPMODE_RX) {
+            tx_led = LED_OFF;
+            rx_led = LED_ON;
+        }
+    }
+#endif /* TARGET_FF_ARDUINO */
+
+volatile bool tx_done;
+
+void txDoneBottom()
+{
+    printf("txDone\r\n");
+    tx_done = true;
+}
+
+PacketParams_t pp;
+
+void startTx()
+{
+    uint8_t buf[2];
+
+    buf[0] = 0; // TX base address
+    buf[1] = 0; // RX base address
+    radio.xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf);
+
+    tx_done = false;
+    radio.start_tx(pp.gfsk.PayloadLength);
+}
+
+unsigned lfsr;
+#define LFSR_INIT       0x1ff
+
+uint8_t get_pn9_byte()
+{
+    uint8_t ret = 0;
+    int xor_out;
+
+    xor_out = ((lfsr >> 5) & 0xf) ^ (lfsr & 0xf);   // four bits at a time
+    lfsr = (lfsr >> 4) | (xor_out << 5);    // four bits at a time
+
+    ret |= (lfsr >> 5) & 0x0f;
+
+    xor_out = ((lfsr >> 5) & 0xf) ^ (lfsr & 0xf);   // four bits at a time
+    lfsr = (lfsr >> 4) | (xor_out << 5);    // four bits at a time
+
+    ret |= ((lfsr >> 1) & 0xf0);
+
+    return ret;
+}
+
+uint8_t I[2];
+uint8_t Q[2];
+
+void rx_callback()
+{
+    uint8_t ch = pc.getc();
+
+    pc.putc(ch);
+
+    switch (ch) {
+        case 'q':
+            radio.writeReg(REG_ADDR_MODCFG+1, ++I[0], 1);
+            printf("I[0]:%02x\r\n", I[0]);
+            break;
+        case 'a':
+            radio.writeReg(REG_ADDR_MODCFG+1, --I[0], 1);
+            printf("I[0]:%02x\r\n", I[0]);
+            break;
+
+        case 'w':
+            radio.writeReg(REG_ADDR_MODCFG+2, ++Q[0], 1);
+            printf("Q[0]:%02x\r\n", Q[0]);
+            break;
+        case 's':
+            radio.writeReg(REG_ADDR_MODCFG+2, --Q[0], 1);
+            printf("Q[0]:%02x\r\n", Q[0]);
+            break;
+
+        case 'e':
+            radio.writeReg(REG_ADDR_MODCFG+3, ++I[1], 1);
+            printf("I[1]:%02x\r\n", I[1]);
+            break;
+        case 'd':
+            radio.writeReg(REG_ADDR_MODCFG+3, --I[1], 1);
+            printf("I[1]:%02x\r\n", I[1]);
+            break;
+
+        case 'r':
+            radio.writeReg(REG_ADDR_MODCFG+4, ++Q[1], 1);
+            printf("Q[1]:%02x\r\n", Q[1]);
+            break;
+        case 'f':
+            radio.writeReg(REG_ADDR_MODCFG+4, --Q[1], 1);
+            printf("Q[1]:%02x\r\n", Q[1]);
+            break;
+
+        default:
+            break;
+    } // ..switch (ch)
+}
+
+void
+init_syncaddr(uint8_t syncNum)
+{
+    uint32_t sa;
+
+    sa = get_pn9_byte();
+    sa <<= 8;
+    sa += get_pn9_byte();
+    sa <<= 8;
+    sa += get_pn9_byte();
+    sa <<= 8;
+    sa += get_pn9_byte();
+
+    printf("sa %08lx\r\n", sa);
+    radio.writeReg(REG_ADDR_SYNCADDR, sa, 4);
+
+    sa = get_pn9_byte();
+    sa <<= 8;
+    sa += get_pn9_byte();
+    sa <<= 8;
+    sa += get_pn9_byte();
+    sa <<= 8;
+    sa += get_pn9_byte();
+
+    printf("sa %08lx\r\n", sa);
+    radio.writeReg(REG_ADDR_SYNCADDR+4, sa, 4);
+}
+ 
+int main()
+{
+    modCfg_t modCfg;
+    uint8_t buf[8];
+    unsigned svcCnt = 0;
+    unsigned preambleLen = 32;
+    ModulationParams_t mp;
+    uint32_t u32;
+    unsigned bps = 1200;
+    bool crcOn = true;
+    unsigned i, fdev_hz;
+
+    printf("\r\nreset\r\n");
+
+    lfsr = LFSR_INIT;
+
+    radio.hw_reset(PINNAME_NRST);
+
+    init_syncaddr(1);
+
+    radio.txDone = txDoneBottom;
+//    radio.rxDone = rx_done;
+//    radio.timeout = timeout_callback;
+    radio.chipModeChange = chipModeChange;
+//    radio.dio1_topHalf = dio1_top_half;
+ 
+    radio.SetDIO2AsRfSwitchCtrl(1);
+
+ 
+    //if (radio.getPacketType() != PACKET_TYPE_GFSK)
+        radio.setPacketType(PACKET_TYPE_GFSK);
+
+    /*************************************************************/
+    pp.gfsk.PreambleLengthHi = preambleLen >> 8;
+    pp.gfsk.PreambleLengthLo = preambleLen;
+    pp.gfsk.PreambleDetectorLength = GFSK_PREAMBLE_DETECTOR_LENGTH_16BITS;
+    pp.gfsk.SyncWordLength = 24; // 0xC194C1
+    pp.gfsk.AddrComp = 0;
+    pp.gfsk.PacketType = HEADER_TYPE_VARIABLE_LENGTH     ;
+    if (crcOn)
+        pp.gfsk.CRCType = GFSK_CRC_2_BYTE;
+    else
+        pp.gfsk.CRCType = GFSK_CRC_OFF;
+ 
+    pp.gfsk.PayloadLength = 192;
+ 
+    radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, pp.buf);
+    /*************************************************************/
+ 
+    u32  = 32 * (XTAL_FREQ_HZ / bps);
+    mp.gfsk.bitrateHi = u32 >> 16; // param1
+    mp.gfsk.bitrateMid = u32 >> 8; // param2
+    mp.gfsk.bitrateLo = u32;       // param3
+    mp.gfsk.PulseShape = GFSK_SHAPE_BT1_0; // param4
+    // param5:
+/*    if (bw_hz < 5800)
+        mp.gfsk.bandwidth = GFSK_RX_BW_4800;
+    else if (bw_hz < 7300)
+        mp.gfsk.bandwidth = GFSK_RX_BW_5800;
+    else if (bw_hz < 9700)
+        mp.gfsk.bandwidth = GFSK_RX_BW_7300;
+    else if (bw_hz < 11700)
+        mp.gfsk.bandwidth = GFSK_RX_BW_9700;
+    else if (bw_hz < 14600)
+        mp.gfsk.bandwidth = GFSK_RX_BW_11700;
+    else if (bw_hz < 19500)
+        mp.gfsk.bandwidth = GFSK_RX_BW_14600;
+    else if (bw_hz < 23400)
+        mp.gfsk.bandwidth = GFSK_RX_BW_19500;
+    else if (bw_hz < 29300)
+        mp.gfsk.bandwidth = GFSK_RX_BW_23400;
+    else if (bw_hz < 39000)
+        mp.gfsk.bandwidth = GFSK_RX_BW_29300;
+    else if (bw_hz < 46900)
+        mp.gfsk.bandwidth = GFSK_RX_BW_39000;
+    else if (bw_hz < 58600)
+        mp.gfsk.bandwidth = GFSK_RX_BW_46900;
+    else if (bw_hz < 78200)
+        mp.gfsk.bandwidth = GFSK_RX_BW_58600;
+    els`e if (bw_hz < 93800)
+        mp.gfsk.bandwidth = GFSK_RX_BW_78200;
+    else if (bw_hz < 117300)
+        mp.gfsk.bandwidth = GFSK_RX_BW_93800;
+    else if (bw_hz < 156200)
+        mp.gfsk.bandwidth = GFSK_RX_BW_117300;
+    else if (bw_hz < 187200)
+        mp.gfsk.bandwidth = GFSK_RX_BW_156200;
+    else if (bw_hz < 234300)
+        mp.gfsk.bandwidth = GFSK_RX_BW_187200;
+    else if (bw_hz < 312000)
+        mp.gfsk.bandwidth = GFSK_RX_BW_234300;
+    else if (bw_hz < 373600)
+        mp.gfsk.bandwidth = GFSK_RX_BW_312000;
+    else if (bw_hz < 467000)
+        mp.gfsk.bandwidth = GFSK_RX_BW_373600;
+    else
+        mp.gfsk.bandwidth = GFSK_RX_BW_467000;*/
+ 
+    mp.gfsk.bandwidth = GFSK_RX_BW_11700;
+    /*
+    fdev_hz = 10000;
+
+    u32 = fdev_hz / FREQ_STEP;
+    mp.gfsk.fdevHi = u32 >> 16; // param6
+    mp.gfsk.fdevMid = u32 >> 8;    // param7
+    mp.gfsk.fdevLo = u32; // param8
+    */
+    mp.gfsk.fdevHi = 0; // param6
+    mp.gfsk.fdevMid = 0;    // param7
+    mp.gfsk.fdevLo = 0; // param8
+ 
+    radio.xfer(OPCODE_SET_MODULATION_PARAMS, 8, 0, mp.buf);
+    /*************************************************************/
+
+    I[0] = radio.readReg(REG_ADDR_MODCFG+1, 1),
+    Q[0] = radio.readReg(REG_ADDR_MODCFG+2, 1),
+    I[1] = radio.readReg(REG_ADDR_MODCFG+3, 1),
+    Q[1] = radio.readReg(REG_ADDR_MODCFG+3, 1),
+
+    modCfg.octet = radio.readReg(REG_ADDR_MODCFG, 1);
+    modCfg.bits.mod_type = 0;
+    radio.writeReg(REG_ADDR_MODCFG, modCfg.octet, 1);
+
+    /*************************************************************/
+
+    radio.setMHz(915.0);
+    radio.set_tx_dbm(true, 14);
+
+    {
+        IrqFlags_t irqEnable;
+        irqEnable.word = 0;
+        irqEnable.bits.TxDone = 1;
+        irqEnable.bits.Timeout = 1;
+
+        buf[0] = irqEnable.word >> 8;    // enable bits
+        buf[1] = irqEnable.word; // enable bits
+        buf[2] = irqEnable.word >> 8;     // dio1
+        buf[3] = irqEnable.word;  // dio1
+        buf[4] = 0; // dio2
+        buf[5] = 0; // dio2
+        buf[6] = 0; // dio3
+        buf[7] = 0; // dio3
+        radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
+    }
+
+    for (i = 0; i < pp.gfsk.PayloadLength; i++) {
+        radio.tx_buf[i] = get_pn9_byte();
+    }
+
+    antswPower = 1;
+
+    startTx();
+
+    for (;;) {
+        if (pc.readable())
+            rx_callback();
+
+        radio.service();
+
+        if (!tx_done) {
+            //
+        } else {
+            wait(0.02);
+
+            for (i = 0; i < pp.gfsk.PayloadLength; i++) {
+                radio.tx_buf[i] = get_pn9_byte();
+            }
+
+            printf("modCfg:%02x\t\t", modCfg.octet);
+            printf("I:%02x  Q:%02x\t\t\tI:%02x  Q:%02x\r\n",
+                (uint8_t)radio.readReg(REG_ADDR_MODCFG+1, 1),
+                (uint8_t)radio.readReg(REG_ADDR_MODCFG+2, 1),
+                (uint8_t)radio.readReg(REG_ADDR_MODCFG+3, 1),
+                (uint8_t)radio.readReg(REG_ADDR_MODCFG+4, 1)
+            );
+            startTx();
+        }
+    } // ..for (;;)
+}
+