sx1261/2 driver

Dependents:   alarm_slave iq_sx126x sx126x_simple_TX_shield_2020a sx126x_simple_RX_shield_2020a ... more

Driver for SX1261 or SX1262

Revision:
2:e6e159c8ab4d
Parent:
1:497af0bd9e53
Child:
3:f6f2f8adcd22
--- a/sx126x.cpp	Tue May 22 14:26:32 2018 -0700
+++ b/sx126x.cpp	Mon Jun 11 11:15:18 2018 -0700
@@ -32,7 +32,7 @@
     buf[5] = 0; // dio2
     buf[6] = 0; // dio3
     buf[7] = 0; // dio3
-    xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, buf);
+    xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
 
 }
 
@@ -61,17 +61,18 @@
     printf("\r\n");
 }
 
+extern RawSerial pc;
 void SX126x::service()
 {
-    //unsigned n = 0;
     IrqFlags_t irqFlags, clearIrqFlags;
     uint8_t buf[4];
 
-    if (busy)
+    if (busy) {
         return;
+    }
 
     while (dio1) {
-        xfer(OPCODE_GET_IRQ_STATUS, 3, buf);
+        xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf);
         irqFlags.word = buf[1] << 8;
         irqFlags.word |= buf[2];
         clearIrqFlags.word = 0;
@@ -86,10 +87,10 @@
                 uint8_t len;
                 float snr, rssi;
                 int8_t s;
-                xfer(OPCODE_GET_RX_BUFFER_STATUS, 3, buf);
+                xfer(OPCODE_GET_RX_BUFFER_STATUS, 0, 3, buf);
                 len = buf[1];
-                ReadBuffer(len);
-                xfer(OPCODE_GET_PACKET_STATUS, 4, buf);
+                ReadBuffer(len, buf[2]);
+                xfer(OPCODE_GET_PACKET_STATUS, 0, 4, buf);
                 rssi = -buf[1] / 2.0;   // TODO FSK
                 s = buf[2];
                 snr = s / 4.0;
@@ -109,36 +110,47 @@
         if (clearIrqFlags.word != 0) {
             buf[0] = clearIrqFlags.word >> 8;
             buf[1] = (uint8_t)clearIrqFlags.word;
-            xfer(OPCODE_CLEAR_IRQ_STATUS, 2, buf);
+            xfer(OPCODE_CLEAR_IRQ_STATUS, 2, 0, buf);
         }
 
     } // ...while (dio1)
 
 } // ..service()
 
-void SX126x::xfer(uint8_t opcode, uint8_t len, uint8_t* ptr)
+void SX126x::xfer(uint8_t opcode, uint8_t wlen, uint8_t rlen, uint8_t* ptr)
 {
+    const uint8_t* stopPtr;
+    const uint8_t* wstop;
+    const uint8_t* rstop;
+    uint8_t nop = 0;
+
     if (sleeping) {
         nss = 0;
         while (busy)
             ;
         sleeping = false;
     } else {
-        //unsigned n = 0;
-        while (busy) {
-            /*wait_us(0.002);
-            if (++n > 200) {
-                return -1;
-            }*/
-        }
+        while (busy)
+            ;
         nss = 0;
     }
 
     spi.write(opcode);
-    while (len > 0) {
-        *ptr = spi.write(*ptr);
-        len--;
-        ptr++;
+
+    wstop = ptr + wlen;
+    rstop = ptr + rlen;
+    if (rlen > wlen)
+        stopPtr = rstop;
+    else
+        stopPtr = wstop;
+
+    for (; ptr < stopPtr; ptr++) {
+        if (ptr < wstop && ptr < rstop)
+            *ptr = spi.write(*ptr);
+        else if (ptr < wstop)
+            spi.write(*ptr);
+        else
+            *ptr = spi.write(nop);    // n >= write length: send NOP
     }
 
     nss = 1;
@@ -170,7 +182,7 @@
     buf[0] = 0x40;
     buf[1] = 0x00;
     buf[2] = 0x00;
-    xfer(OPCODE_SET_TX, 3, buf);
+    xfer(OPCODE_SET_TX, 3, 0, buf);
 
     chipMode = CHIPMODE_TX;
 }
@@ -182,12 +194,11 @@
     buf[0] = timeout >> 16;
     buf[1] = timeout >> 8;
     buf[2] = timeout;
-    xfer(OPCODE_SET_RX, 3, buf);
+    xfer(OPCODE_SET_RX, 3, 0, buf);
 
     chipMode = CHIPMODE_RX;
 }
 
-#define MHZ_TO_FRF      1048576 // = (1<<25) / Fxtal_MHz
 uint8_t SX126x::setMHz(float MHz)
 {
     unsigned frf = MHz * MHZ_TO_FRF;
@@ -197,21 +208,27 @@
     buf[1] = frf >> 16;
     buf[2] = frf >> 8;
     buf[3] = frf;
-    xfer(OPCODE_SET_RF_FREQUENCY, 4, buf);
+    xfer(OPCODE_SET_RF_FREQUENCY, 4, 0, buf);
     return buf[3];
 }
 
+float SX126x::getMHz()
+{
+    uint32_t frf = readReg(REG_ADDR_RFFREQ, 4);
+    return frf / (float)MHZ_TO_FRF;
+}
+
 void SX126x::setPacketType(uint8_t type)
 {
-    xfer(OPCODE_SET_PACKET_TYPE, 1, &type);
+    xfer(OPCODE_SET_PACKET_TYPE, 1, 0, &type);
 }
 
 void SX126x::SetDIO2AsRfSwitchCtrl(uint8_t en)
 {
-    xfer(OPCODE_SET_DIO2_AS_RFSWITCH, 1, &en);
+    xfer(OPCODE_SET_DIO2_AS_RFSWITCH, 1, 0, &en);
 }
 
-void SX126x::ReadBuffer(uint8_t size)
+void SX126x::ReadBuffer(uint8_t size, uint8_t offset)
 {
     unsigned i;
     while (busy)
@@ -220,7 +237,7 @@
     nss = 0;
 
     spi.write(OPCODE_READ_BUFFER);
-    spi.write(0);   // offset
+    spi.write(offset);
     spi.write(0);   // NOP
     i = 0;
     for (i = 0; i < size; i++) {
@@ -258,7 +275,7 @@
         else if (dbm < -3)
             dbm = -3;
     }
-    xfer(OPCODE_SET_PA_CONFIG, 4, buf);
+    xfer(OPCODE_SET_PA_CONFIG, 4, 0, buf);
 
     if (is1262 && dbm > 18) {
         /* OCP is set by chip whenever SetPaConfig() is called */
@@ -269,7 +286,7 @@
     buf[0] = dbm;
     //if (opt == 0) txco
     buf[1] = SET_RAMP_200U;
-    xfer(OPCODE_SET_TX_PARAMS, 2, buf);
+    xfer(OPCODE_SET_TX_PARAMS, 2, 0, buf);
 }
 
 void SX126x::writeReg(uint16_t addr, uint32_t data, uint8_t len)
@@ -282,13 +299,13 @@
         buf[n+1] = (uint8_t)data;
         data >>= 8;
     }
-    xfer(OPCODE_WRITE_REGISTER, 2+len, buf);
+    xfer(OPCODE_WRITE_REGISTER, 2+len, 2+len, buf);
 }
 
 void SX126x::setStandby(stby_t stby)
 {
     uint8_t octet = stby;
-    xfer(OPCODE_SET_STANDBY, 1, &octet);
+    xfer(OPCODE_SET_STANDBY, 1, 0, &octet);
 
     chipMode = CHIPMODE_NONE;
 }
@@ -300,7 +317,7 @@
     sc.octet = 0;
     sc.bits.rtcWakeup = rtcWakeup;
     sc.bits.warmStart = warmStart;
-    xfer(OPCODE_SET_SLEEP, 1, &sc.octet);
+    xfer(OPCODE_SET_SLEEP, 1, 0, &sc.octet);
 
     chipMode = CHIPMODE_NONE;
 }
@@ -327,7 +344,7 @@
     uint8_t buf[7];
     buf[0] = addr >> 8;
     buf[1] = (uint8_t)addr;
-    xfer(OPCODE_READ_REGISTER, 3+len, buf);
+    xfer(OPCODE_READ_REGISTER, 2, 3+len, buf);
     for (i = 0; i < len; i++) {
         ret <<= 8;
         ret |= buf[i+3];