changeset 3978:c968e80489a0

driver/si446x: report AFC freq offset
author Alexandre Becoulet <alexandre.becoulet@free.fr>
date Mon, 09 Jul 2018 17:01:22 +0200
parents 841bf310b65f
children 3ddeb1eba4d7
files drivers/rfpacket/si446x/modem_calc.c drivers/rfpacket/si446x/modem_calc.h drivers/rfpacket/si446x/si446x.c drivers/rfpacket/si446x/si446x.h drivers/rfpacket/si446x/si446x_spi.bc libdevice/include/device/class/rfpacket.h
diffstat 6 files changed, 137 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/drivers/rfpacket/si446x/modem_calc.c	Mon Jul 09 16:58:18 2018 +0200
+++ b/drivers/rfpacket/si446x/modem_calc.c	Mon Jul 09 17:01:22 2018 +0200
@@ -68,24 +68,6 @@
 
 #define CONFIG_DRIVER_RFPACKET_SI446X_PFM 2	/* 1 or 2 */
 
-enum si446x_modulation_e {
-	MOD_RAW,
-	MOD_OOK,
-	MOD_2FSK,
-	MOD_2GFSK,
-	MOD_4FSK,
-	MOD_4GFSK,
-};
-
-enum si446x_mc_cfg_msk_e {
-	SI446X_MC_MOD          = 1,
-	SI446X_MC_FREQUENCY    = 2,
-	SI446X_MC_DEVIATION    = 4,
-	SI446X_MC_BW           = 8,
-	SI446X_MC_DRATE        = 16,
-	SI446X_MC_ENCODING     = 32,
-};
-
 #ifdef __MUTEKH__
 
 #include <device/class/rfpacket.h>
@@ -135,13 +117,13 @@
 	return (uint32_t)(r + .5);
 }
 
-static bool_t modem_calc(struct si446x_rf_regs_s *out,
-                         enum si446x_mc_cfg_msk_e mask,
-                         enum si446x_modulation_e mod,
-                         uint32_t freq, uint32_t rate,
-                         uint32_t fdev, uint32_t rxbw,
-                         uint32_t channel_spacing,
-                         bool_t manchester)
+bool_t modem_calc(struct si446x_rf_regs_s *out,
+                  uint32_t *synth_ratio,
+                  enum si446x_modulation_e mod,
+                  uint32_t freq, uint32_t rate,
+                  uint32_t fdev, uint32_t rxbw,
+                  uint32_t channel_spacing,
+                  bool_t manchester)
 {
   const struct si446x_synth_regs_s *synth;
   struct si446x_freq_ctl_regs_s *freq_ctl = &out->freq;
@@ -308,6 +290,8 @@
   freq_ctl->frac_1 = freq_frac >> 8;
   freq_ctl->frac_0 = freq_frac;
 
+  *synth_ratio = CONFIG_DRIVER_RFPACKET_SI446X_FREQ_XO * CONFIG_DRIVER_RFPACKET_SI446X_PFM * 16 / freq_band;
+
   /********************* FREQ_CONTROL_CHANNEL_STEP_SIZE */
 
   uint32_t ch_step = round((double)channel_spacing
@@ -652,14 +636,16 @@
   double rxbw = atof(argv[4]);
   double rate = atof(argv[5]);
   uint32_t manchester = !!atoi(argv[6]);
+  uint32_t sr;
 
   struct si446x_rf_regs_s r;
-  if (!modem_calc(&r, -1, mod, freq, rate, fdev, rxbw, 0x200000, manchester))
+  if (!modem_calc(&r, &sr, mod, freq, rate, fdev, rxbw, 0x200000, manchester))
     {
       fprintf(stderr, "error\n");
       return -1;
     }
 
+  fprintf(stderr, "synth ratio 0x%X\n", sr);
   printf("set MODEM_MOD_TYPE 0x%02X\n", r.modem.mod_type);
   printf("set MODEM_MAP_CONTROL 0x%02X\n", r.modem.map_control);
   printf("set MODEM_DSM_CTRL 0x%02X\n", r.modem.dsm_ctrl);
@@ -785,70 +771,4 @@
   return 0;
 }
 
-#else
-
-size_t si446x_modem_configure(struct si446x_rf_regs_s *out,
-                              const struct dev_rfpacket_rf_cfg_s *rf_cfg,
-                              const struct dev_rfpacket_pk_cfg_s *pk_cfg)
-{
-  static const uint8_t tab[] = {
-    [DEV_RFPACKET_FSK * 2] = MOD_2FSK,
-    [DEV_RFPACKET_FSK * 2 + 1] = MOD_4FSK,
-    [DEV_RFPACKET_GFSK * 2] = MOD_2GFSK,
-    [DEV_RFPACKET_GFSK * 2 + 1] = MOD_4GFSK,
-    [DEV_RFPACKET_ASK * 2] = MOD_OOK,
-  };
-
-  uint8_t idx = rf_cfg->mod * 2;
-  uint32_t fdev = 0;
-
-  switch (rf_cfg->mod)
-    {
-    case DEV_RFPACKET_GFSK:
-    case DEV_RFPACKET_FSK:
-      {
-        const struct dev_rfpacket_rf_cfg_fsk_s * c =
-          const_dev_rfpacket_rf_cfg_fsk_s_cast(rf_cfg);
-
-        switch (c->symbols)
-          {
-#ifdef CONFIG_DRIVER_RFPACKET_SI446X_MOD_2FSK
-          case 2:
-            break;
 #endif
-#ifdef CONFIG_DRIVER_RFPACKET_SI446X_MOD_4FSK
-          case 4:
-            break;
-#endif
-          default:
-            return 0;
-          }
-
-        fdev = c->deviation;
-
-        idx += (c->symbols == 4);
-        break;
-      }
-#ifdef CONFIG_DRIVER_RFPACKET_SI446X_MOD_00K
-    case DEV_RFPACKET_ASK:
-      {
-        const struct dev_rfpacket_rf_cfg_ask_s * c =
-          const_dev_rfpacket_rf_cfg_ask_s_cast(rf_cfg);
-
-        if (c->symbols != 2)
-          return 0;
-
-        break;
-      }
-#endif
-    default:
-      return 0;
-    }
-
-  bool_t manchester = (pk_cfg->encoding == DEV_RFPACKET_MANCHESTER);
-
-  return modem_calc(out, -1, tab[idx], rf_cfg->frequency, rf_cfg->drate,
-                    fdev, rf_cfg->bw, rf_cfg->chan_spacing, manchester);
-}
-
-#endif
--- a/drivers/rfpacket/si446x/modem_calc.h	Mon Jul 09 16:58:18 2018 +0200
+++ b/drivers/rfpacket/si446x/modem_calc.h	Mon Jul 09 17:01:22 2018 +0200
@@ -150,12 +150,28 @@
 };
 
 struct si446x_rf_regs_s;
-struct dev_rfpacket_rf_cfg_s;
-struct dev_rfpacket_pk_cfg_s;
 
-size_t si446x_modem_configure(struct si446x_rf_regs_s *out,
-			      const struct dev_rfpacket_rf_cfg_s *rf_cfg,
-                              const struct dev_rfpacket_pk_cfg_s *pk_cfg);
+/*
+  synth_ratio can be used to convert between AFC freq_offset and frequency in Hz:
+  F = (freq_offset * synth_ratio) >> 23
+*/
+
+enum si446x_modulation_e {
+	MOD_RAW,
+	MOD_OOK,
+	MOD_2FSK,
+	MOD_2GFSK,
+	MOD_4FSK,
+	MOD_4GFSK,
+};
+
+bool_t modem_calc(struct si446x_rf_regs_s *out,
+                  uint32_t *synth_ratio,
+                  enum si446x_modulation_e mod,
+                  uint32_t freq, uint32_t rate,
+                  uint32_t fdev, uint32_t rxbw,
+                  uint32_t channel_spacing,
+                  bool_t manchester);
 
 #endif
 
--- a/drivers/rfpacket/si446x/si446x.c	Mon Jul 09 16:58:18 2018 +0200
+++ b/drivers/rfpacket/si446x/si446x.c	Mon Jul 09 17:01:22 2018 +0200
@@ -260,6 +260,85 @@
   return 0;
 }
 
+static bool_t
+si446x_modem_configure(struct si446x_ctx_s *pv,
+                       struct si446x_rf_regs_s *out,
+                       const struct dev_rfpacket_rf_cfg_s *rf_cfg,
+                       const struct dev_rfpacket_pk_cfg_s *pk_cfg)
+{
+  static const uint8_t tab[] = {
+    [DEV_RFPACKET_FSK * 2] = MOD_2FSK,
+    [DEV_RFPACKET_FSK * 2 + 1] = MOD_4FSK,
+    [DEV_RFPACKET_GFSK * 2] = MOD_2GFSK,
+    [DEV_RFPACKET_GFSK * 2 + 1] = MOD_4GFSK,
+    [DEV_RFPACKET_ASK * 2] = MOD_OOK,
+  };
+
+  uint8_t idx = rf_cfg->mod * 2;
+  uint32_t fdev = 0;
+
+  switch (rf_cfg->mod)
+    {
+    case DEV_RFPACKET_GFSK:
+    case DEV_RFPACKET_FSK:
+      {
+        const struct dev_rfpacket_rf_cfg_fsk_s * c =
+          const_dev_rfpacket_rf_cfg_fsk_s_cast(rf_cfg);
+
+        switch (c->symbols)
+          {
+#ifdef CONFIG_DRIVER_RFPACKET_SI446X_MOD_2FSK
+          case 2:
+            break;
+#endif
+#ifdef CONFIG_DRIVER_RFPACKET_SI446X_MOD_4FSK
+          case 4:
+            break;
+#endif
+          default:
+            return 0;
+          }
+
+        fdev = c->deviation;
+
+        idx += (c->symbols == 4);
+        break;
+      }
+#ifdef CONFIG_DRIVER_RFPACKET_SI446X_MOD_00K
+    case DEV_RFPACKET_ASK:
+      {
+        const struct dev_rfpacket_rf_cfg_ask_s * c =
+          const_dev_rfpacket_rf_cfg_ask_s_cast(rf_cfg);
+
+        if (c->symbols != 2)
+          return 0;
+
+        break;
+      }
+#endif
+    default:
+      return 0;
+    }
+
+  bool_t manchester;
+
+  switch (pk_cfg->encoding)
+    {
+    case DEV_RFPACKET_CLEAR:
+      manchester = 0;
+      break;
+    case DEV_RFPACKET_MANCHESTER:
+      manchester = 1;
+      break;
+    default:
+      return 0;
+    }
+
+  return modem_calc(out, &pv->synth_ratio, tab[idx], rf_cfg->frequency, rf_cfg->drate,
+                    fdev, rf_cfg->bw, rf_cfg->chan_spacing, manchester);
+}
+
+
 static inline error_t si446x_build_rf_config(struct si446x_ctx_s *pv,
                                              struct si446x_rf_regs_s *out,
                                              struct dev_rfpacket_rq_s *rq)
@@ -268,7 +347,7 @@
 
   const struct dev_rfpacket_rf_cfg_s *cfg = rq->rf_cfg;
 
-  if (!si446x_modem_configure(out, rq->rf_cfg, rq->pk_cfg))
+  if (!si446x_modem_configure(pv, out, rq->rf_cfg, rq->pk_cfg))
     return -ENOTSUP;
 
   /** Configure RSSI_threshold */
@@ -568,20 +647,6 @@
   }
 }
 
-
-static inline void si446x_check_rxc_freq(struct si446x_ctx_s *pv, struct dev_rfpacket_rq_s *rq)
-{
-  struct dev_rfpacket_rf_cfg_s * cfg = (struct dev_rfpacket_rf_cfg_s *)rq->rf_cfg;
-
-  uint32_t freq = cfg->frequency + rq->channel * cfg->chan_spacing;
-
-  if (pv->frequency != freq)
-    {
-      pv->rssi = SET_RSSI(SI446X_RSSI_AVERAGE_DEFAULT) << 8;
-      pv->frequency = freq;
-    }
-}
-
 static inline void si446x_start_rx(struct si446x_ctx_s *pv, struct dev_rfpacket_rq_s *rq)
 {
   assert(pv->state == SI446X_STATE_READY);
@@ -593,6 +658,9 @@
 
   pv->rq = rq;
 
+  struct dev_rfpacket_rf_cfg_s * cfg = (struct dev_rfpacket_rf_cfg_s *)rq->rf_cfg;
+  uint32_t freq = cfg->frequency + rq->channel * cfg->chan_spacing;
+
   switch (rq->type)
   {
     case DEV_RFPACKET_RQ_RX:
@@ -600,6 +668,7 @@
 
       pv->deadline = rq->deadline ? rq->deadline : t;
       pv->timeout = pv->deadline + rq->lifetime;
+      pv->frequency = freq;
 
       si446x_rfp_set_state(pv, SI446X_STATE_RX);
 
@@ -610,7 +679,11 @@
     case DEV_RFPACKET_RQ_RX_CONT:
       si446x_printk("RC\n");
 
-      si446x_check_rxc_freq(pv, rq);
+      if (pv->frequency != freq)
+        {
+          pv->rssi = SET_RSSI(SI446X_RSSI_AVERAGE_DEFAULT) << 8;
+          pv->frequency = freq;
+        }
 
       pv->flags |= SI446X_FLAGS_RX_CONTINOUS;
 
@@ -1135,6 +1208,7 @@
   rx->err = err;
   rx->carrier = GET_RSSI(pv->carrier) << 3;
   rx->rssi = GET_RSSI(pv->rssi >> 8) << 3;
+  rx->frequency = pv->frequency + (((int64_t)pv->synth_ratio * pv->afc_offset) >> 23);
   rx->timestamp = pv->timestamp;
   rx->channel = rq->channel;
   if (rq->anchor == DEV_RFPACKET_TIMESTAMP_START)
--- a/drivers/rfpacket/si446x/si446x.h	Mon Jul 09 16:58:18 2018 +0200
+++ b/drivers/rfpacket/si446x/si446x.h	Mon Jul 09 17:01:22 2018 +0200
@@ -188,6 +188,8 @@
   uint8_t carrier, jam_rssi;
   uint32_t rssi;
   /* Frequency associated to last Rssi measurment */
+  int16_t afc_offset;
+  uint32_t synth_ratio;
   uint32_t frequency;
 
   enum si446x_state_s state:8;
--- a/drivers/rfpacket/si446x/si446x_spi.bc	Mon Jul 09 16:58:18 2018 +0200
+++ b/drivers/rfpacket/si446x/si446x_spi.bc	Mon Jul 09 17:01:22 2018 +0200
@@ -521,21 +521,19 @@
 
 .func get_rssi
         .input %6 link
-        .clobber %10, %2, %11, %12, %13
-        .output %0 current, %1 latched
+        .clobber %10, %11, %12, %13
+        .output %0 current, %1 latched, %2 afc
         cst8                    %0,                     SI446X_MODEM_STATUS_CMD
         pack8			%0,                     1
         call16                  %poll_gpio:link,        poll_gpio
         spi_wr                  %0,                     1,	CS_PULSE
         call16                  %poll_cts_rsp:link,     poll_cts_rsp
-        spi_rd                  %0,                     4,	CS_END
-        unpack32le		%0,                     1,      4
-        mov                     %1,                     %0
-        shi32r                  %current,               16
-        shi32r                  %latched,               24
-        cst32			%2,                     0xff,    0
-        and32			%current,               %2
-        and32			%latched,               %2
+        spi_rd                  %10,                    8,	CS_END
+        unpack16be              %10,                    4,      8
+        mov                     %afc,                   %13
+        mov                     %0,                     %11
+        pack16be                %0,                     1,      2
+        unpack8                 %0,                     2
         ret                     %link
 .endfunc
 
@@ -624,6 +622,7 @@
    rssi:
         call8                   %get_rssi:link,         get_rssi
         st8e                    %get_rssi:latched,      %R_CTX_PV,     _offsetof(si446x_ctx_s, carrier)
+        st16e                   %get_rssi:afc,          %R_CTX_PV,     _offsetof(si446x_ctx_s, afc_offset)
         end
 .endfunc
 
--- a/libdevice/include/device/class/rfpacket.h	Mon Jul 09 16:58:18 2018 +0200
+++ b/libdevice/include/device/class/rfpacket.h	Mon Jul 09 17:01:22 2018 +0200
@@ -439,6 +439,9 @@
   /** RX signal power over noise power ratio. */
   dev_rfpacket_pwr_t                snr;
 
+  /** Measured RX frequency */
+  uint32_t                          frequency;
+
   /** Channel of the received packet. */
   uint8_t                           channel;