IQ modulation on sx126x

Dependencies:   sx126x

main.cpp

Committer:
Wayne Roberts
Date:
2018-07-24
Revision:
1:061c7250788a

File content as of revision 1:061c7250788a:

#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 (;;)
}