summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/drivers/net/ieee802154/dw3000.h2
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_calib.c77
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_calib.h13
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core.c48
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core.h1
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_mcps.c2
-rw-r--r--kernel/net/mcps802154/nl.c2
-rw-r--r--mac/fira_access.c41
-rw-r--r--mac/include/net/mcps802154.h5
-rwxr-xr-xtools/calibrations/pdoa_lut_generation203
10 files changed, 350 insertions, 44 deletions
diff --git a/kernel/drivers/net/ieee802154/dw3000.h b/kernel/drivers/net/ieee802154/dw3000.h
index 3e1ce7f..03c6f14 100644
--- a/kernel/drivers/net/ieee802154/dw3000.h
+++ b/kernel/drivers/net/ieee802154/dw3000.h
@@ -272,6 +272,7 @@ struct dw3000_power_control {
* @ant: Antennas currently connected to RF1 & RF2 ports respectively
* @antpair_spacing_mm_q11: Holds selected antennas pair spacing from calibration table
* @pdoaOffset: Calibrated PDOA offset
+ * @pdoaLut: Pointer to calibrated PDOA to AoA look-up table
* @rmarkerOffset: Calibrated rmarker offset
* @promisc: Promiscuous mode enabled?
* @hw_addr_filt: HW filter configuration
@@ -292,6 +293,7 @@ struct dw3000_config {
s8 ant[2];
int antpair_spacing_mm_q11;
s16 pdoaOffset;
+ const dw3000_pdoa_lut_t *pdoaLut;
u32 rmarkerOffset;
bool promisc;
struct ieee802154_hw_addr_filt hw_addr_filt;
diff --git a/kernel/drivers/net/ieee802154/dw3000_calib.c b/kernel/drivers/net/ieee802154/dw3000_calib.c
index b1cfe5c..4ec15a7 100644
--- a/kernel/drivers/net/ieee802154/dw3000_calib.c
+++ b/kernel/drivers/net/ieee802154/dw3000_calib.c
@@ -23,6 +23,9 @@
#include "dw3000.h"
#include "dw3000_txpower_adjustment.h"
+/* UWB High band 802.15.4a-2007. Only channels 5 & 9 for DW3000. */
+#define DW3000_SUPPORTED_CHANNELS ((1 << 5) | (1 << 9))
+
/* clang-format off */
#define CHAN_PRF_PARAMS (4 * DW3000_CALIBRATION_PRF_MAX)
#define ANT_CHAN_PARAMS (CHAN_PRF_PARAMS * DW3000_CALIBRATION_CHANNEL_MAX)
@@ -42,6 +45,7 @@
#define CAL_INFO(m) DW_INFO(calib_data.m)
#define OTP_INFO(m) DW_INFO(otp_data.m)
+#define CAL_PDOA_LUT(m) DW_INFO(calib_data.m)
#define PRF_CAL_INFO(b,x) \
CAL_INFO(b.prf[x].ant_delay), \
@@ -153,6 +157,78 @@ static const char *const dw3000_calib_keys[MAX_CALIB_KEYS + 1] = {
};
/* clang-format on */
+const dw3000_pdoa_lut_t dw3000_default_lut_ch5 = {
+ /* clang-format off */
+ { 0xe6de, 0xf36f },
+ { 0xe88b, 0xf36f },
+ { 0xea38, 0xf5b0 },
+ { 0xebe5, 0xf747 },
+ { 0xed92, 0xf869 },
+ { 0xef3f, 0xf959 },
+ { 0xf0ec, 0xfa2e },
+ { 0xf299, 0xfaf1 },
+ { 0xf445, 0xfba7 },
+ { 0xf5f2, 0xfc53 },
+ { 0xf79f, 0xfcf9 },
+ { 0xf94c, 0xfd9a },
+ { 0xfaf9, 0xfe36 },
+ { 0xfca6, 0xfed0 },
+ { 0xfe53, 0xff69 },
+ { 0x0000, 0x0000 },
+ { 0x01ad, 0x0097 },
+ { 0x035a, 0x0130 },
+ { 0x0507, 0x01ca },
+ { 0x06b4, 0x0266 },
+ { 0x0861, 0x0307 },
+ { 0x0a0e, 0x03ad },
+ { 0x0bbb, 0x0459 },
+ { 0x0d67, 0x050f },
+ { 0x0f14, 0x05d2 },
+ { 0x10c1, 0x06a7 },
+ { 0x126e, 0x0797 },
+ { 0x141b, 0x08b9 },
+ { 0x15c8, 0x0a50 },
+ { 0x1775, 0x0c91 },
+ { 0x1922, 0x0c91 }
+ /* clang-format on */
+};
+
+const dw3000_pdoa_lut_t dw3000_default_lut_ch9 = {
+ /* clang-format off */
+ { 0xe6de, 0xf701 },
+ { 0xe88b, 0xf7ff },
+ { 0xea38, 0xf8d2 },
+ { 0xebe5, 0xf98d },
+ { 0xed92, 0xfa38 },
+ { 0xef3f, 0xfad7 },
+ { 0xf0ec, 0xfb6d },
+ { 0xf299, 0xfbfc },
+ { 0xf445, 0xfc86 },
+ { 0xf5f2, 0xfd0c },
+ { 0xf79f, 0xfd8f },
+ { 0xf94c, 0xfe0f },
+ { 0xfaf9, 0xfe8d },
+ { 0xfca6, 0xff09 },
+ { 0xfe53, 0xff85 },
+ { 0x0000, 0x0000 },
+ { 0x01ad, 0x007b },
+ { 0x035a, 0x00f7 },
+ { 0x0507, 0x0173 },
+ { 0x06b4, 0x01f1 },
+ { 0x0861, 0x0271 },
+ { 0x0a0e, 0x02f4 },
+ { 0x0bbb, 0x037a },
+ { 0x0d67, 0x0404 },
+ { 0x0f14, 0x0493 },
+ { 0x10c1, 0x0529 },
+ { 0x126e, 0x05c8 },
+ { 0x141b, 0x0673 },
+ { 0x15c8, 0x072e },
+ { 0x1775, 0x0801 },
+ { 0x1922, 0x08ff }
+ /* clang-format on */
+};
+
int dw3000_calib_parse_key(struct dw3000 *dw, const char *key, void **param)
{
int i;
@@ -243,6 +319,7 @@ int dw3000_calib_update_config(struct dw3000 *dw)
antpair_calib = &dw->calib_data.antpair[antpair];
/* Update PDOA offset */
config->pdoaOffset = antpair_calib->ch[chanidx].pdoa_offset;
+ config->pdoaLut = &antpair_calib->ch[chanidx].pdoa_lut;
/* Update antpair spacing */
config->antpair_spacing_mm_q11 = antpair_calib->spacing_mm_q11;
diff --git a/kernel/drivers/net/ieee802154/dw3000_calib.h b/kernel/drivers/net/ieee802154/dw3000_calib.h
index 274f4b4..f934376 100644
--- a/kernel/drivers/net/ieee802154/dw3000_calib.h
+++ b/kernel/drivers/net/ieee802154/dw3000_calib.h
@@ -57,7 +57,16 @@ enum dw3000_calibration_prf {
/**
* DW3000_CALIBRATION_PDOA_LUT_MAX - number of value in PDOA LUT table
*/
-#define DW3000_CALIBRATION_PDOA_LUT_MAX 7
+#define DW3000_CALIBRATION_PDOA_LUT_MAX 31
+
+/**
+ * typedef dw3000_pdoa_lut_t - PDoA LUT array type
+ */
+typedef s16 dw3000_pdoa_lut_t[DW3000_CALIBRATION_PDOA_LUT_MAX][2];
+
+/* Default LUTs, theorical values for Monalisa antenna (20.8mm) */
+extern const dw3000_pdoa_lut_t dw3000_default_lut_ch5;
+extern const dw3000_pdoa_lut_t dw3000_default_lut_ch9;
/**
* DW3000_DEFAULT_ANT_DELAY - antenna delay default value
@@ -121,7 +130,7 @@ struct dw3000_antenna_calib {
*/
struct dw3000_antenna_pair_calib_chan {
s16 pdoa_offset;
- u32 pdoa_lut[DW3000_CALIBRATION_PDOA_LUT_MAX];
+ dw3000_pdoa_lut_t pdoa_lut;
};
/**
diff --git a/kernel/drivers/net/ieee802154/dw3000_core.c b/kernel/drivers/net/ieee802154/dw3000_core.c
index 57dd3d9..4d72dd4 100644
--- a/kernel/drivers/net/ieee802154/dw3000_core.c
+++ b/kernel/drivers/net/ieee802154/dw3000_core.c
@@ -4493,12 +4493,12 @@ int dw3000_set_pdoa(struct dw3000 *dw, u8 mode)
}
/**
-* dw3000_read_pdoa - Read the PDOA result.
+* dw3000_read_pdoa() - Read the PDOA result.
* @dw: The DW device.
*
* This is used to read the PDOA result, it is the phase difference between
* either the Ipatov and STS POA, or the two STS POAs, depending on the PDOA
-* mode of operation. (POA - Phase Of Arrival).
+* mode of operation. (PDoA - Phase Difference On Arrival).
* NOTE: To convert to degrees: float pdoa_deg =
* ((float)pdoa / (1 << 11)) * 180 / M_PI.
*
@@ -4541,6 +4541,42 @@ s16 dw3000_read_pdoa(struct dw3000 *dw)
}
/**
+ * dw3000_pdoa_to_aoa_lut() - Convert PDoA to AoA.
+ * @dw: the DW device
+ * @pdoa_rad_q11: the PDoA value as returned by dw3000_read_pdoa()
+ *
+ * Convert PDoA (in radian, encoded as a Q11 fixed
+ * point number) to AoA value using calibration look-up table.
+ *
+ * Return: AoA value interpolated from LUT values.
+ */
+s16 dw3000_pdoa_to_aoa_lut(struct dw3000 *dw, s16 pdoa_rad_q11)
+{
+ const dw3000_pdoa_lut_t *lut = dw->config.pdoaLut;
+ int a = 0, b = DW3000_CALIBRATION_PDOA_LUT_MAX - 1;
+ s16 delta_pdoa, delta_aoa;
+
+ if (pdoa_rad_q11 < (*lut)[0][0])
+ return (*lut)[0][1];
+ if (pdoa_rad_q11 >= (*lut)[DW3000_CALIBRATION_PDOA_LUT_MAX - 1][0])
+ return (*lut)[DW3000_CALIBRATION_PDOA_LUT_MAX - 1][1];
+
+ while (a != b) {
+ int m = (a + b) / 2;
+ if (pdoa_rad_q11 < (*lut)[m][0])
+ b = m;
+ else
+ a = m + 1;
+ }
+
+ delta_pdoa = (*lut)[a][0] - (*lut)[a - 1][0];
+ delta_aoa = (*lut)[a][1] - (*lut)[a - 1][1];
+
+ return (*lut)[a][1] +
+ (delta_aoa * (pdoa_rad_q11 - (*lut)[a][0])) / delta_pdoa;
+}
+
+/**
* dw3000_set_sts_pdoa() - set device's STS & PDOA mode
* @dw: the DW device
* @sts_mode: the STS mode
@@ -5879,6 +5915,14 @@ void dw3000_init_config(struct dw3000 *dw)
/* Ensure default antennas pair spacing is configured */
dw->calib_data.antpair[i].spacing_mm_q11 =
DW3000_DEFAULT_ANTPAIR_SPACING;
+ memcpy(dw->calib_data.antpair[i]
+ .ch[DW3000_CALIBRATION_CHANNEL_5]
+ .pdoa_lut,
+ dw3000_default_lut_ch5, sizeof(dw3000_pdoa_lut_t));
+ memcpy(dw->calib_data.antpair[i]
+ .ch[DW3000_CALIBRATION_CHANNEL_9]
+ .pdoa_lut,
+ dw3000_default_lut_ch9, sizeof(dw3000_pdoa_lut_t));
}
/* Set default antenna ports configuration */
dw->calib_data.ant[0].port = 0;
diff --git a/kernel/drivers/net/ieee802154/dw3000_core.h b/kernel/drivers/net/ieee802154/dw3000_core.h
index bbde90a..aae0c9c 100644
--- a/kernel/drivers/net/ieee802154/dw3000_core.h
+++ b/kernel/drivers/net/ieee802154/dw3000_core.h
@@ -342,6 +342,7 @@ int dw3000_set_rx_antennas(struct dw3000 *dw, int antpairidx,
bool pdoa_enabled);
s16 dw3000_read_pdoa(struct dw3000 *dw);
+s16 dw3000_pdoa_to_aoa_lut(struct dw3000 *dw, s16 pdoa_rad_q11);
int dw3000_read_sts_timestamp(struct dw3000 *dw, u64 *sts_ts);
int dw3000_read_sts_quality(struct dw3000 *dw, s16 *acc_qual);
diff --git a/kernel/drivers/net/ieee802154/dw3000_mcps.c b/kernel/drivers/net/ieee802154/dw3000_mcps.c
index 3164520..4c8b27c 100644
--- a/kernel/drivers/net/ieee802154/dw3000_mcps.c
+++ b/kernel/drivers/net/ieee802154/dw3000_mcps.c
@@ -387,6 +387,8 @@ static int rx_get_frame(struct mcps802154_llhw *llhw, struct sk_buff **skb,
info->ranging_pdoa_rad_q11 = dw3000_read_pdoa(dw);
info->ranging_pdoa_spacing_mm_q11 =
config->antpair_spacing_mm_q11;
+ info->ranging_aoa_rad_q11 =
+ dw3000_pdoa_to_aoa_lut(dw, info->ranging_pdoa_rad_q11);
}
/* In case of STS */
if (info->flags & MCPS802154_RX_FRAME_INFO_RANGING_STS_TIMESTAMP_RCTU) {
diff --git a/kernel/net/mcps802154/nl.c b/kernel/net/mcps802154/nl.c
index 45fc4cb..755e0ae 100644
--- a/kernel/net/mcps802154/nl.c
+++ b/kernel/net/mcps802154/nl.c
@@ -1007,7 +1007,7 @@ static int mcps802154_nl_get_calibration(struct sk_buff *skb,
struct sk_buff *msg;
void *hdr;
char *key;
- u32 tmp[7];
+ u32 tmp[32];
int err;
int r;
diff --git a/mac/fira_access.c b/mac/fira_access.c
index 0d8742b..f7faff4 100644
--- a/mac/fira_access.c
+++ b/mac/fira_access.c
@@ -44,43 +44,6 @@ static struct mcps802154_access *
fira_access_controlee(struct fira_local *local, struct fira_session *session);
/**
- * phase_to_rad_fp() - compute the angle(AoA) from phase(PDOA) with fixed-point.
- * @pdoa_rad_q11: phase of arrival in fixed-point.
- * @spacing_mm_q11: spacing between antenna in mm in fixed-point.
- *
- * Return: Angle of Arrival in fixed-point too.
- */
-static s16 phase_to_rad_fp(s16 pdoa_rad_q11, int spacing_mm_q11)
-{
- /**
- * Speed of light in air.
- * static const long long speed_of_light_m_per_s = 299702547ull;
- * static const long long freq_hz = 6.5e9;
- * Constant to amplify/decrease value A and B, and so decrease
- * error added by fixed-point.
- * Through N, A and B are closed to INT16_MAX.
- * static const int N = 762;
- * static const long long num = N * K * speed_of_light_m_per_s;
- * static const double dem = freq_hz * 2.0 * M_PI;
- * static const s16 A = num / dem;
- * s16 B = N * spacing_mm_q11 / 1000;
- *
- * To be sure to have a optimize code, inline A declaration.
- * A = 11452
- *
- * A will change with CHAN index.
- * B is calculated using given antenna spacing that come from the mcps
- * driver from the calibration table.
- */
- static const s16 A = 11452;
- s16 B = (s16)(762 * spacing_mm_q11 / 1000);
- s16 x = div_fp(mult_fp(pdoa_rad_q11, A), B);
- /* Saturate between -1 to +1 for asyn. */
- x = x > K ? K : x < -K ? -K : x;
- return asin_fp(x);
-}
-
-/**
* fira_access_setup_frame() - Fill an access frame from a FiRa slot.
* @local: FiRa context.
* @session: Session.
@@ -229,8 +192,8 @@ static void fira_rx_frame_ranging(struct fira_local *local,
bool pdoa_fom_info_present =
info->flags & MCPS802154_RX_FRAME_INFO_RANGING_PDOA_FOM;
s16 local_pdoa_q11 = info->ranging_pdoa_rad_q11;
- s16 local_aoa_q11 = phase_to_rad_fp(
- local_pdoa_q11, info->ranging_pdoa_spacing_mm_q11);
+ s16 local_aoa_q11 = info->ranging_aoa_rad_q11;
+
if (params->rx_antenna_pair_azimuth == slot->rx_ant_pair) {
local_aoa = &ranging_info->local_aoa_azimuth;
} else if (params->rx_antenna_pair_elevation ==
diff --git a/mac/include/net/mcps802154.h b/mac/include/net/mcps802154.h
index 416884a..045b8c2 100644
--- a/mac/include/net/mcps802154.h
+++ b/mac/include/net/mcps802154.h
@@ -347,6 +347,11 @@ struct mcps802154_rx_frame_info {
*/
int ranging_pdoa_spacing_mm_q11;
/**
+ * @ranging_aoa_rad_q11: AoA interpolated by the driver from its
+ * calibration LUT. unit is rad multiplied by 2048 (RDEV only).
+ */
+ int ranging_aoa_rad_q11;
+ /**
* @ranging_sts_timestamp_diffs_rctu: For each SRMARKERx, difference
* between the measured timestamp and the expected timestamp relative to
* RMARKER in ranging count time unit (ERDEV only). When STS mode is
diff --git a/tools/calibrations/pdoa_lut_generation b/tools/calibrations/pdoa_lut_generation
new file mode 100755
index 0000000..dc850ee
--- /dev/null
+++ b/tools/calibrations/pdoa_lut_generation
@@ -0,0 +1,203 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import math
+import json
+from optparse import OptionParser
+
+# This defaulr value is sync with:
+# dw3000_calib.c:DW3000_CALIBRATION_PDOA_LUT_MAX
+DW3000_CALIBRATION_PDOA_LUT_MAX = 31
+
+usage="""%s [options]
+
+This script aims to dump a binary blob suitable for uwb-stack calibration file.
+It works in two modes :
+ 1. Input JSON LUT
+ 2. Antenna spacing and formula
+
+== Input JSON LUT ==
+It takes a JSON input on stdin and dumps the corresponding blob on stdout.
+The JSON input must be a list of either:
+ * lists containing 2 items of type float, 1st is assumed to be PDoA, 2nd AoA,
+ * maps containing 'aoa' and 'pdoa' keys, and corresponding values of type float.
+ float values are assumed to be in radian unit.
+
+== Antenna spacing and formula ==
+This mode uses the theorical math formula to compute AoA value from PDoA measurement.
+It also uses the antenna spacing parameter, please ensure to provide the right value.
+2 sub modes are possible:
+ * PDoA value are provided in list of float that matches the LUT size
+ * --no-json option is specified or empty input is provided, then the tool will
+ split the [-Pi, Pi] range in %d equal parts and use it as PDoA value list
+"""%(
+ os.path.basename(sys.argv[0]),
+ DW3000_CALIBRATION_PDOA_LUT_MAX,
+ )
+
+
+# ==== Fixed point / math utils ====
+
+Q = 11
+K = 2 ** Q
+S16_MAX = ((2 ** 15) - 1)
+S16_MIN = -(2 ** 15)
+
+speed_of_light_m_per_s = 299702547
+
+def freq_hz(chan):
+ if chan == 5:
+ return 6.5e9
+ elif chan == 9:
+ return 7.9872e9
+ else:
+ raise ValueError("Channel must be either 5 or 9")
+
+def sat_uf(x):
+ return min(S16_MAX, max(S16_MIN, x))
+
+def float_to_q11(x):
+ return sat_uf(round(x * K))
+
+pi_q = float_to_q11(math.pi)
+
+def pdoa_to_aoa_rad(x, chan, antenna_dist_m):
+ L_M = speed_of_light_m_per_s / freq_hz(chan)
+ phase_m = x * L_M / (2.0 * math.pi)
+ rad = phase_m / antenna_dist_m
+ rad = min(1.0, max(-1.0, rad))
+ return math.asin(rad)
+
+# ==================================
+
+def blob_item(pdoa, aoa, fmt, byteorder):
+ pdoa_q11 = float_to_q11(pdoa)
+ aoa_q11 = float_to_q11(aoa)
+ pdoa_bytes = pdoa_q11.to_bytes(2, byteorder=byteorder, signed=True)
+ aoa_bytes = aoa_q11.to_bytes(2, byteorder=byteorder, signed=True)
+ return fmt%(pdoa_bytes[0], pdoa_bytes[1], aoa_bytes[0], aoa_bytes[1])
+
+def input_json_lut(pdoa_lut, options):
+ print("Generating LUT using 'input JSON LUT' mode...")
+ print("LUT = %s"%str(pdoa_lut))
+ if not isinstance(pdoa_lut, list) \
+ or (options.size_check and (len(pdoa_lut) != options.lut_size)):
+ raise ValueError("input JSON must be list of size %d"
+ %(str(options.lut_size)))
+
+ blob = ""
+ first_val = True
+ internal_pdoa_lut = []
+ for item in pdoa_lut:
+ if isinstance(item, list) and len(item) == 2:
+ pdoa = item[0]
+ aoa = item[1]
+ elif isinstance(item, dict):
+ # NB: exception raised if key not provided in input data
+ pdoa = item['pdoa']
+ aoa = item['aoa']
+ else:
+ raise ValueError("input JSON list item must of type list \
+[float, float] (PDoA then AoA) or map {'aoa':float, 'pdoa':float}")
+ internal_pdoa_lut.append((pdoa, aoa))
+
+ internal_pdoa_lut.sort(key=lambda x: x[0])
+
+ for item in internal_pdoa_lut:
+ pdoa = item[0]
+ aoa = item[1]
+ if first_val:
+ first_val = False
+ else:
+ blob += options.sep
+ blob += blob_item(pdoa, aoa, options.fmt, options.byteorder)
+
+ return blob
+
+def antenna_spacing_and_formula(pdoa_values, options):
+ print("Generating LUT using 'antenna spacing and formula' mode...")
+ print("PDoA values = %s"%(str(pdoa_values)))
+ print("Antenna spacing (mm) = %f"%(options.antenna_spacing / 1000.0))
+ if not isinstance(pdoa_values, list) \
+ or (options.size_check and (len(pdoa_values) != options.lut_size)):
+ raise ValueError("input JSON must be list of size %d"
+ %(options.lut_size))
+ blob = ""
+ first_val = True
+
+ for value in pdoa_values:
+ pdoa = float(value) # would raise TypeError
+ aoa = pdoa_to_aoa_rad(pdoa, options.channel,
+ options.antenna_spacing / 1000000.0)
+ print("\t%f\t=>\t%f"%(pdoa, aoa))
+ if first_val:
+ first_val = False
+ else:
+ blob += options.sep
+ blob += blob_item(pdoa, aoa, options.fmt, options.byteorder)
+ return blob
+
+def float_range(start, stop, step):
+ while start < stop:
+ yield float(start)
+ start += step
+
+if __name__ == "__main__":
+ parser = OptionParser(usage=usage)
+ parser.add_option("--channel", dest="channel", type="int", default=5,
+ help="UWB Channel (5 or 9, default is 5)")
+ parser.add_option("--formula-mode", dest="formula_mode",
+ action="store_true", default=False,
+ help="selects formula mode")
+ parser.add_option("--antenna-spacing", dest="antenna_spacing",
+ type="int", default=20800,
+ help="sets the antenna pair spacing used in formula \
+ mode, unit is micrometers (default value 20800 \
+ matches Mona Lisa design).")
+ parser.add_option("--byteorder", dest="byteorder",
+ type="string", default=sys.byteorder,
+ help="Override byte order. Default is the system's \
+ byteorder (%s)"%(sys.byteorder))
+ parser.add_option("--lut-size", dest="lut_size",
+ type="int", default=DW3000_CALIBRATION_PDOA_LUT_MAX,
+ help="Override default lut size (%d)"%(DW3000_CALIBRATION_PDOA_LUT_MAX))
+ parser.add_option("--no-size-check", dest="size_check",
+ action="store_false", default=True,
+ help="skips length of the input map.")
+ parser.add_option("--dump-c-array", dest="dump_c_array",
+ action="store_true", default=False,
+ help="Dumps a C array instead of calib blob")
+ parser.add_option("--no-input", dest="read_stdin",
+ action="store_false", default=True,
+ help="Skips reading input on stdin")
+ (options, args) = parser.parse_args()
+
+ if options.dump_c_array:
+ options.sep = ",\n"
+ options.fmt = "\t{ 0x%02x%02x, 0x%02x%02x }"
+ options.byteorder = 'big'
+ else:
+ options.sep = ":"
+ options.fmt = "%02x:%02x:%02x:%02x"
+
+ txt_input = ""
+ if options.read_stdin:
+ for line in sys.stdin:
+ txt_input += line
+
+ if options.formula_mode:
+ if txt_input:
+ pdoa_values = json.loads(txt_input)
+ else:
+ step = 2 * math.pi / (options.lut_size-1)
+ pdoa_values = list(float_range(-math.pi, math.pi, step))
+ blob = antenna_spacing_and_formula(pdoa_values, options)
+ else:
+ pdoa_lut = json.loads(txt_input)
+ blob = input_json_lut(pdoa_lut, options)
+
+ if options.dump_c_array:
+ print("const dw3000_pdoa_lut_t pdoa_lut = {\n" + blob + "\n};")
+ else:
+ print("antX.antY.chN.pdoa_lut " + blob)