1 /*
2  * Copyright (c) 2022-2024, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*
33  *  ======== ble_cs.c ========
34  */
35 
36 #include <stdint.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #include <ti/log/Log.h>
41 
42 #include <ti/drivers/rcl/RCL_Command.h>
43 #include <ti/drivers/rcl/RCL_Buffer.h>
44 #include <ti/drivers/rcl/RCL_Scheduler.h>
45 
46 #include <ti/drivers/rcl/hal/hal.h>
47 #include <ti/drivers/rcl/commands/ble_cs.h>
48 
49 #include <ti/devices/DeviceFamily.h>
50 #include DeviceFamily_constructPath(inc/hw_lrfdtxf.h)
51 #include DeviceFamily_constructPath(inc/hw_lrfdrxf.h)
52 #include DeviceFamily_constructPath(inc/hw_lrfddbell.h)
53 #include DeviceFamily_constructPath(inc/hw_lrfdpbe.h)
54 #include DeviceFamily_constructPath(inc/hw_lrfdpbe32.h)
55 #include DeviceFamily_constructPath(inc/hw_lrfdmdm.h)
56 #include DeviceFamily_constructPath(inc/hw_lrfdmdm32.h)
57 #include DeviceFamily_constructPath(inc/hw_lrfdrfe.h)
58 #include DeviceFamily_constructPath(inc/hw_lrfdrfe32.h)
59 #include DeviceFamily_constructPath(inc/hw_lrfds2r.h)
60 #include DeviceFamily_constructPath(inc/rfe_common_ram_regs.h)
61 #include DeviceFamily_constructPath(inc/pbe_generic_ram_regs.h)
62 #include DeviceFamily_constructPath(inc/pbe_common_ram_regs.h)
63 #include DeviceFamily_constructPath(inc/pbe_ble5_ram_regs.h)
64 #include DeviceFamily_constructPath(inc/pbe_ble_cs_ram_regs.h)
65 #include DeviceFamily_constructPath(inc/pbe_ble_cs_regdef_regs.h)
66 
67 #ifndef OCTOPUS
68 #include DeviceFamily_constructPath(inc/hw_types.h)
69 #include DeviceFamily_constructPath(inc/hw_memmap.h)
70 #include DeviceFamily_constructPath(inc/hw_gpio.h)
71 #include DeviceFamily_constructPath(inc/hw_ioc.h)
72 #endif
73 
74 #define BLE_CS_BASE_FREQ_MHZ            2402
75 #define BLE_CS_MAX_CHANNEL              78
76 #define BLE_CS_NUM_CHANNELS             90
77 #define BLE_CS_NUM_INVALID_CHANNELS     7
78 #define BLE_CS_SILENT_CHANNEL           100
79 #define BLE_CS_NUM_PERMUTATION          24
80 #define BLE_CS_S2R_OVERSAMPLE_RATE      4
81 #define BLE_CS_S2R_MEMORY_OFFSET        0x0C00
82 #define BLE_CS_TXFIFO_BASE_ADDR         128
83 #define BLE_CS_TXFIFO_LEN               96
84 #define BLE_CS_RXFIFO_BASE_ADDR         224
85 #define BLE_CS_RXFIFO_LEN               160
86 #define BLE_CS_FIRST_BATCH_SIZE         2
87 #define BLE_CS_TONE_QUALITY_GOOD_THR    25
88 #define BLE_CS_TONE_QUALITY_MEDIUM_THR  50
89 #define BLE_CS_TONE_EXTENSION_INITIATOR_TX 0b01
90 #define BLE_CS_TONE_EXTENSION_REFLECTOR_TX 0b10
91 #define DECODE_ANTENNA(x, y)            (((x) >> ((y)*2)) & 0x03)
92 #define ENCODE_ANTENNA(x, y)            (((x) << ((y)*4)))
93 #define INT16_MSB(x)                    (((x) >> 8) & 0xFF)
94 #define INT16_LSB(x)                    ((x) & 0xFF)
95 
96 /* Prepare constant terms for step specific calculations */
97 #define T1US  48  // Constant 1us at 48MHz
98 #define T3US  144 // Constant 3us at 48MHz
99 #define TRD   240 // Constant 5us at 48MHz
100 #define TGD   480 // Constant 10us at 48MHz
101 #define TPLT  960 // Constant 20us at 48MHz
102 #define TPYL  0   // Unknown at this point
103 
104 /*
105  *  ======== Execution status ========
106  */
107 struct
108 {
109     struct {
110         RCL_CommandStatus endStatus;
111     } common;
112     struct {
113         uint32_t startTime;
114     } ble_cs;
115 } bleCsHandlerState;
116 
117 /* Storage to decompress data */
118 RCL_CmdBleCs_Step_Internal       step;
119 RCL_CmdBleCs_StepResult_Internal result;
120 
121 /* Precalculated base terms */
122 uint32_t tStepLut[RCL_CmdBleCs_StepMode_Length];
123 uint16_t tAdjALut[RCL_CmdBleCs_StepMode_Length];
124 uint16_t tAdjBLut[RCL_CmdBleCs_StepMode_Length];
125 uint16_t tAntALut[RCL_CmdBleCs_StepMode_Length];
126 uint16_t tAntBLut[RCL_CmdBleCs_StepMode_Length];
127 uint16_t tRttAdjustLut[RCL_CmdBleCs_StepMode_Length];
128 
129 /*
130  *  ======== Type for indexing antenna sequence ========
131  */
132 typedef union {
133     struct {
134         uint8_t a0 : 2;
135         uint8_t a1 : 2;
136         uint8_t a2 : 2;
137         uint8_t a3 : 2;
138     } a;
139     uint8_t apn;
140 } RCL_AntennaPath_t;
141 
142 /*
143  *  ======== Type for mapping antenna permutation to antenna sequence ========
144  */
145 typedef struct {
146     uint8_t numPath : 3;    /*!< Total number of antenna path */
147     uint8_t numPerm : 5;    /*!< Total number of permutation possible with this configuration */
148     uint8_t increment;      /*!< How to index the permutation table */
149     RCL_AntennaPath_t ap[2];
150 } RCL_AntennaConfig_t;
151 
152 /*
153  *  ======== Antenna permutation table ========
154  */
155 const RCL_AntennaPath_t antennaPermutation[BLE_CS_NUM_PERMUTATION] = {
156     /*[ 0:5 ]=*/{{0,1,2,3}}, {{0,1,3,2}}, {{0,2,3,1}}, {{0,2,1,3}}, {{0,3,1,2}}, {{0,3,2,1}},
157     /*[ 6:11]=*/{{1,0,2,3}}, {{1,0,3,2}}, {{1,2,3,0}}, {{1,2,0,3}}, {{1,3,0,2}}, {{1,3,2,0}},
158     /*[12:17]=*/{{2,0,1,3}}, {{2,0,3,1}}, {{2,1,3,0}}, {{2,1,0,3}}, {{2,3,0,1}}, {{2,3,1,0}},
159     /*[18:24]=*/{{3,0,2,1}}, {{3,0,1,2}}, {{3,1,2,0}}, {{3,1,0,2}}, {{3,2,0,1}}, {{3,2,1,0}}
160 };
161 
162 /*
163  *  ======== Antenna permutation selection mapping ========
164  */
165 const RCL_AntennaConfig_t antennaConfig[RCL_CmdBleCs_AntennaConfig_Length] = {
166     /*1x1=*/{.numPath=1, .numPerm=1,  .increment=0, .ap={/*initiator=*/{{0,0,0,0}}, /*reflector=*/{{0,0,0,0}}}},
167     /*2x1=*/{.numPath=2, .numPerm=2,  .increment=6, .ap={/*initiator=*/{{0,1,0,0}}, /*reflector=*/{{0,0,0,0}}}},
168     /*3x1=*/{.numPath=3, .numPerm=6,  .increment=3, .ap={/*initiator=*/{{0,1,2,0}}, /*reflector=*/{{0,0,0,0}}}},
169     /*4x1=*/{.numPath=4, .numPerm=24, .increment=1, .ap={/*initiator=*/{{0,1,2,3}}, /*reflector=*/{{0,0,0,0}}}},
170     /*1x2=*/{.numPath=2, .numPerm=2,  .increment=6, .ap={/*initiator=*/{{0,0,0,0}}, /*reflector=*/{{0,1,0,0}}}},
171     /*1x3=*/{.numPath=3, .numPerm=6,  .increment=3, .ap={/*initiator=*/{{0,0,0,0}}, /*reflector=*/{{0,1,2,0}}}},
172     /*1x4=*/{.numPath=4, .numPerm=24, .increment=1, .ap={/*initiator=*/{{0,0,0,0}}, /*reflector=*/{{0,1,2,3}}}},
173     /*2x2=*/{.numPath=4, .numPerm=24, .increment=1, .ap={/*initiator=*/{{0,0,1,1}}, /*reflector=*/{{0,1,1,0}}}}
174 };
175 
176 /*
177  *  ======== Type of configuration of MCE and FIDC accumulator used for PCT measurement ========
178  */
179 typedef union {
180     struct {
181         uint8_t period       : 2;   /*!< Configures the accumulation period of DEMFIDC module */
182         uint8_t numIteration : 2;   /*!< Configures how many times to run the accumulator period */
183         uint8_t fracWaitAdj  : 4;
184         uint8_t fracWait;
185     };
186     uint16_t val;
187 } RCL_PctConfig_t;
188 
189 typedef union {
190     struct {
191         uint8_t magnIteration;
192         uint8_t reserved;
193     };
194     uint16_t val;
195 } RCL_MagnConfig_t;
196 
197 typedef struct {
198     int16_t mode0[2];
199     int16_t mode1[2];
200     int16_t mode2[2];
201     int16_t mode3[2];
202 } RCL_Tadjust_t;
203 
204 /*
205  *  ======== Type of configuration for phy specific settings ========
206  */
207 typedef struct {
208     /* Modem specific registers */
209     uint16_t        baud;
210     uint16_t        symmap;
211     uint16_t        demmisc2;
212     uint16_t        demmisc3;
213     uint16_t        rssioffset;
214 
215     /* Timing parameters [48 MHz units unless specified otherwise] */
216     uint16_t        tPostProcessDiv1;   /*!<  Duration set aside for post processing */
217     uint16_t        tPostProcessDiv12;  /*!<  Duration set aside for post processing */
218     uint16_t        tRxTimeoutI0;       /*!<  Initiator must terminate packet reception before end of step */
219     uint16_t        tRxTimeoutI3;       /*!<  Initiator must terminate packet reception before end of step */
220     int16_t         tPilotAdjust;       /*!<  Pilot tone need to be adjusted with shaper delay */
221     uint16_t        tStartup;           /*!<  Duration set aside for starting up the topSMs and start to emit a tone on the antenna */
222     uint16_t        tPacket;            /*!<  Duration of packet [preamble + AA + Trailer] */
223     uint16_t        tRxTimeoutRn;       /*!<  Reception timeout on reflector side */
224     uint16_t        tInfiniteRx;        /*!<  Correction of step duration when packet reception is used as anchor point */
225     uint16_t        tTr;                /*!<  Duration of trailer bits */
226     uint16_t        tCorr;              /*!<  Time between signal on antenna and correlation event */
227     uint16_t        tDem;               /*!<  Time between signal on antenna and demodulation completed*/
228     uint16_t        tFidc;              /*!<  Time between signal on antenna and FIDC */
229     uint16_t        tTxModDelay;        /*!<  Time between modulator and signal on antenna (mostly shaper delay) */
230     uint16_t        tTimestampDelay1;   /*!<  Sum of delays between signal on antenna vs capture on timer by HW for mode-1 */
231     uint16_t        tTimestampDelay3;   /*!<  Sum of delays between signal on antenna vs capture on timer by HW for mode-3 */
232 
233     /* Accumulator period and iteration number in order to fit into the same TPM period. */
234     RCL_PctConfig_t pctConfig[RCL_CmdBleCs_Tpm_Length];
235 
236     /* Magnitude accumulator configuration used by RFE for tone quality estimation */
237     RCL_MagnConfig_t magnConfig[RCL_CmdBleCs_Tpm_Length];
238 
239     /* Adjustment of TIP period per mode */
240     RCL_Tadjust_t tAdj[RCL_CmdBleCs_Role_Length];
241 
242     /* Adjustment of antenna timings for mode 2 & 3 */
243     RCL_Tadjust_t tAnt[RCL_CmdBleCs_Role_Length];
244 } RCL_PhyConfig_t;
245 
246 //#define FE_8MHZ 1
247 /*
248  *  ======== Configuration per PHY ========
249  */
250 const RCL_PhyConfig_t phyConfigLut[RCL_CmdBleCs_Phy_Length] = {
251     #ifdef FE_8MHZ
252     {   /* Phy_1M @ 8MHZ*/
253         .baud       = 0x4000,
254         .symmap     = 0x001F,
255         .demmisc2   = 0x15F8,
256         .demmisc3   = 0x10A1,
257         .rssioffset = 0x0049,
258 
259         /* Theory */
260         .tPacket           = 2112, // 8+32+4 bits = 44us
261         .tTr               = 192,  // 4us
262 
263         /* Tuned */
264         .tStartup          = 93,  // 1.937us (pbe_timer_event -> mce_timer start)
265         .tTxModDelay       = 245, // 5.109us (wait -> signal on shaper)
266         .tPilotAdjust      = 264, // 5.5us
267         .tPostProcessDiv1  = 936, // 19.5us
268         .tPostProcessDiv12 = 78,  // 19.5us
269         .tInfiniteRx       = 60,  // 1.25us
270 
271         .tFidc             = 161, // 3.35us
272         .tCorr             = 244, // 5.08us
273         .tDem              = 783, // 16.31us
274 
275         .tRxTimeoutI0      = RCL_BLE_CS_US_TO_MCE_TIMER(70),
276         .tRxTimeoutI3      = RCL_BLE_CS_US_TO_MCE_TIMER(56),
277         .tRxTimeoutRn      = RCL_BLE_CS_US_TO_MCE_TIMER(76),
278 
279         /* Sum of demodulation and modulation delay (HW only) */
280         .tTimestampDelay1  = 477,
281         .tTimestampDelay3  = 481,
282 
283         .pctConfig = {
284             /*TPM = 10US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL32 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S),  .numIteration = 2, .fracWait = 32,  .fracWaitAdj = 9},
285             /*TPM = 20US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL128 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S), .numIteration = 1, .fracWait = 128, .fracWaitAdj = 0},
286             /*TPM = 40US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL128 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S), .numIteration = 2, .fracWait = 128, .fracWaitAdj = 0}
287         },
288 
289         .magnConfig = {
290             /*TPM = 10US*/{.magnIteration = 5},
291             /*TPM = 20US*/{.magnIteration = 14},
292             /*TPM = 40US*/{.magnIteration = 30}
293         },
294 
295         .tAdj = { /* { pkt-tn, tn-tn} */
296             {
297                 /* Initiator */
298                 .mode0 = {0, 0},
299                 .mode1 = {0, 0},
300                 .mode2 = {-147, +112},
301                 .mode3 = {0, +28}
302             },
303             {
304                 /* Reflector */
305                 .mode0 = {+11, 0},
306                 .mode1 = {+11, 0},
307                 .mode2 = {-66, -96},
308                 .mode3 = {-50, -54}
309             }
310         },
311 
312         .tAnt = {
313             {
314                 /* Initiator */
315                 .mode2 = {0, 0},
316                 .mode3 = {0, 0}
317             },
318             {
319                 /* Reflector */
320                 .mode2 = {0, 0},
321                 .mode3 = {0, 0}
322             }
323         }
324     },
325     #else
326     {   /* Phy_1M @ 4MHZ*/
327         .baud       = 0x4000,
328         .symmap     = 0x001F,
329         .demmisc2   = 0x05F8,
330         .demmisc3   = 0x1082,
331         .rssioffset = 0x0049,
332 
333         /* Theory */
334         .tPacket           = 2112, // 8+32+4 bits = 44us
335         .tTr               = 192,  // 4us
336 
337         /* Tuned */
338         .tStartup          = 93,  // 1.937us (pbe_timer_event -> mce_timer start)
339         .tTxModDelay       = 245, // 5.109us (wait -> signal on shaper)
340         .tPilotAdjust      = 259, // 5.39us
341         .tPostProcessDiv1  = 936, // 19.5us
342         .tPostProcessDiv12 = 78,  // 19.5us
343         .tInfiniteRx       = 60,  // 1.25us
344 
345         .tFidc             = 264, // 5.5us
346         .tCorr             = 377, // 7.85us
347         .tDem              = 914, // 19.05us
348 
349         .tRxTimeoutI0      = RCL_BLE_CS_US_TO_MCE_TIMER(70),
350         .tRxTimeoutI3      = RCL_BLE_CS_US_TO_MCE_TIMER(56),
351         .tRxTimeoutRn      = RCL_BLE_CS_US_TO_MCE_TIMER(76),
352 
353         /* Sum of demodulation and modulation delay (HW only) */
354         .tTimestampDelay1  = 603,
355         .tTimestampDelay3  = 601,
356 
357         .pctConfig = {
358             /*TPM = 10US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL32 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S),  .numIteration = 1, .fracWait = 32,  .fracWaitAdj = 0},
359             /*TPM = 20US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL32 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S),  .numIteration = 2, .fracWait = 32,  .fracWaitAdj = 0},
360             /*TPM = 40US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL128 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S), .numIteration = 1, .fracWait = 128, .fracWaitAdj = 0}
361         },
362 
363         .magnConfig = {
364             /*TPM = 10US*/{.magnIteration = 3},
365             /*TPM = 20US*/{.magnIteration = 6},
366             /*TPM = 40US*/{.magnIteration = 14}
367         },
368 
369         .tAdj = { /* { pkt-tn, tn-tn} */
370             {
371                 /* Initiator */
372                 .mode0 = {0, 0},
373                 .mode1 = {0, 0},
374                 .mode2 = {-147, +64},
375                 .mode3 = {0, -22}
376             },
377             {
378                 /* Reflector */
379                 .mode0 = {+27, 0},
380                 .mode1 = {+27, 0},
381                 .mode2 = {-94, -48},
382                 .mode3 = {-96, +16}
383             }
384         },
385 
386         .tAnt = {
387             {
388                 /* Initiator */
389                 .mode2 = {+60, 0},
390                 .mode3 = {+66, 0}
391             },
392             {
393                 /* Reflector */
394                 .mode2 = {+105, 0},
395                 .mode3 = {+105, 0}
396             }
397         }
398     },
399     #endif
400     {   /* Phy_2M */
401         .baud       = 0x8000,
402         .symmap     = 0x002E,
403         .demmisc2   = 0x04F8,
404         .demmisc3   = 0x1081,
405         .rssioffset = 0x0049,
406 
407         /* Theory */
408         .tPacket           = 1248, // 16+32+4bit = 26us
409         .tTr               = 96,   // 2us
410 
411         /* Tuned */
412         .tStartup          = 95,   // 1.979us (pbe_timer_event -> mce_timer start)
413         .tTxModDelay       = 142,  // 2.957us (wait -> signal on shaper)
414         .tPilotAdjust      = 156,  // 4.02us
415         .tPostProcessDiv1  = 720,  // 15us
416         .tPostProcessDiv12 = 60,   // 15us
417         .tInfiniteRx       = 60,   // 1.25us
418 
419         .tFidc             = 146, // 3.05us
420         .tCorr             = 204, // 4.25us
421         .tDem              = 565, // 11.77us
422 
423         .tRxTimeoutI0      = 2448+24, // 51us   MCE
424         .tRxTimeoutI3      = 1776,    // 37us   MCE
425         .tRxTimeoutRn      = 3096,    // 64.5us MCE
426 
427         /* Sum of demodulation and modulation delay (HW only) */
428         .tTimestampDelay1  = 333,
429         .tTimestampDelay3  = 335,
430 
431         .pctConfig = {
432             /*TPM = 10US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL32 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S),  .numIteration = 2, .fracWait = 32,  .fracWaitAdj = 9},
433             /*TPM = 20US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL128 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S), .numIteration = 1, .fracWait = 128, .fracWaitAdj = 0},
434             /*TPM = 40US*/{.period = (LRFDMDM_DEMFIDC0_ACCPERIOD_SMPL128 >> LRFDMDM_DEMFIDC0_ACCPERIOD_S), .numIteration = 2, .fracWait = 128, .fracWaitAdj = 0}
435         },
436 
437         .magnConfig = {
438             /*TPM = 10US*/{.magnIteration = 5},
439             /*TPM = 20US*/{.magnIteration = 14},
440             /*TPM = 40US*/{.magnIteration = 30}
441         },
442 
443         .tAdj = {
444             {
445                 /* Initiator */
446                 .mode0 = {0, 0},
447                 .mode1 = {0, 0},
448                 .mode2 = {-48, +107},
449                 .mode3 = {0, 0}
450             },
451             {
452                 /* Reflector */
453                 .mode0 = {+32, 0},
454                 .mode1 = {+32, 0},
455                 .mode2 = {-38, -93},
456                 .mode3 = {-60, -20}
457             }
458         },
459 
460         .tAnt = {
461             {
462                 /* Initiator */
463                 .mode2 = {+63, 0},
464                 .mode3 = {+63, 0}
465             },
466             {
467                 /* Reflector */
468                 .mode2 = {+129, 0},
469                 .mode3 = {+129, 0}
470             }
471         }
472     }
473 };
474 
475 /* Frequency compensation value due to the fixed CMIXN value use. Resolution is 4x FOFF unit.
476    Calculated based on the formula:
477    foffError = 4x ((((1<<21) * fif) / (BLE_CS_BASE_FREQ_MHZ + pStepI->channelIdx) / 1e3)
478              - ((1<<21) * (1024 - pStepI->cmixn) / 288 / 1024)); */
479 const int8_t foffErrorLut[BLE_CS_NUM_CHANNELS] = {
480     /*2402 MHz =*/  38, 34, 34, 34, 30, 30, 30, 26,
481     /*2410 MHz =*/  26, 26, 26, 22, 22, 22, 18, 18, 18, 14,
482     /*2420 MHz =*/  14, 14, 10, 10, 10, 10,  6,  6,  6,  2,
483     /*2430 MHz =*/   2,  2, -2, -2, -2, -2, -6, -6, -6,-10,
484     /*2440 MHz =*/ -10,-10,-14,-14,-14,-14,-18,-18,-18,-22,
485     /*2450 MHz =*/ -22,-22,-26,-26,-26,-26,-30,-30,-30,-34,
486     /*2460 MHz =*/ -34,-34,-34,-38,-38,-38,-42,-42,-42,-46,
487     /*2470 MHz =*/ -46,-46,-46,-50,-50,-50,-54,-54,-54,-54,
488     /*2480 MHz =*/ -58,-58,-58,-62,-62,-62,-62,-66,-66,-66
489 };
490 
491 /* Look up table of payload length in units of MCE Timer at rate of [1M]. Scaling dynamically if needed. */
492 const uint16_t payloadLut[RCL_CmdBleCs_Payload_Length] = {
493     /*0 bits =*/   RCL_BLE_CS_US_TO_MCE_TIMER(0),
494     /*32 bits =*/  RCL_BLE_CS_US_TO_MCE_TIMER(32),
495     /*64 bits =*/  RCL_BLE_CS_US_TO_MCE_TIMER(64),
496     /*96 bits =*/  RCL_BLE_CS_US_TO_MCE_TIMER(96),
497     /*128 bits =*/ RCL_BLE_CS_US_TO_MCE_TIMER(128)
498 };
499 
500 /* Forward declarations */
501 static RCL_MultiBuffer* RCL_Handler_BLE_CS_findBufferFitNumberOfBytes(List_List *pHead, uint16_t numBytes);
502 static void RCL_Handler_BLE_CS_configureTxRxFifo(RCL_CmdBleCs* pCmd);
503 static void RCL_Handler_BLE_CS_retrieveAndStoreNextResult(RCL_CmdBleCs* pCmd, bool forceBufferToFinishState);
504 static void RCL_Handler_BLE_CS_fetchAndforwardNextStep(RCL_CmdBleCs* pCmd);
505 static RCL_Events RCL_Handler_BLE_CS_preFillTxBuffer(RCL_CmdBleCs* pCmd);
506 static RCL_Events RCL_Handler_BLE_CS_readWriteBuffer(RCL_CmdBleCs* pCmd, bool forceBufferToFinishState);
507 static bool RCL_Handler_BLE_CS_transferFinishedBuffers(List_List *pSrc, List_List *pDst);
508 static void RCL_Handler_BLE_CS_configureS2R(RCL_CmdBleCs *pCmd);
509 static RCL_Events RCL_Handler_BLE_CS_readS2RSamples(RCL_CmdBleCs *pCmd);
510 static void RCL_Handler_BLE_CS_readStatistics(RCL_CmdBleCs *pCmd);
511 static void RCL_Handler_BLE_CS_preprocessCommand(RCL_CmdBleCs *pCmd);
512 static void RCL_Handler_BLE_CS_preprocessStep(RCL_CmdBleCs *pCmd, RCL_CmdBleCs_Step *pStep, RCL_CmdBleCs_Step_Internal *pStepI);
513 static RCL_CmdBleCs_StepResult_Internal* RCL_Handler_BLE_CS_fetchNextStepResult(RCL_CmdBleCs *pCmd);
514 static int16_t RCL_Handler_BLE_CS_convertFreqOffset(int16_t foffMeasured);
515 static int16_t RCL_Handler_BLE_CS_convertRtt(RCL_CmdBleCs *pCmd, uint8_t mode, int8_t channel, int16_t foff, uint8_t payload, bool secondToneExtensionSlot, float toAD, uint16_t corrBefore, uint16_t corrPeak, uint16_t corrAfter);
516 static uint32_t RCL_Handler_BLE_CS_convertPct(int16_t pct_i, int16_t pct_q, uint8_t channelIdx);
517 static uint8_t RCL_Handler_BLE_CS_convertPctQuality(uint16_t qMin, uint16_t qMax, uint16_t qAvg, bool toneExtensionSlot, bool toneExpected);
518 static uint16_t RCL_Handler_BLE_CS_estimateStepResultLength(RCL_CmdBleCs *pCmd,RCL_CmdBleCs_StepResult_Internal* src);
519 static uint16_t RCL_Handler_BLE_CS_convertStepResult(RCL_CmdBleCs* pCmd, uint8_t *dst, RCL_CmdBleCs_StepResult_Internal* src);
520 static RCL_CommandStatus RCL_Handler_BLE_CS_findPbeErrorEndStatus(uint16_t pbeEndStatus);
521 
522 /*
523  *  ======== Traverse multibuffer list looking for space ========
524  */
RCL_Handler_BLE_CS_findBufferFitNumberOfBytes(List_List * pHead,uint16_t numBytes)525 static RCL_MultiBuffer* RCL_Handler_BLE_CS_findBufferFitNumberOfBytes(List_List *pHead, uint16_t numBytes)
526 {
527     /* Start search from the head of list */
528     RCL_MultiBuffer *pBuffer = RCL_MultiBuffer_head(pHead);
529 
530     /* Traverse the chain of buffers and find the first free one */
531     do {
532         pBuffer = RCL_MultiBuffer_findFirstWritableBuffer(pBuffer);
533 
534         /* Avoid NULL pointer dereferencing */
535         if (pBuffer)
536         {
537             /* Check for available space */
538             if (pBuffer->length - pBuffer->tailIndex >= numBytes)
539             {
540                 /* Mark the buffer to be written */
541                 pBuffer->state = RCL_BufferStateInUse;
542 
543                 break;
544             }
545             else
546             {
547                 /* The buffer will not fit the incoming number of bytes */
548                 pBuffer->state = RCL_BufferStateFinished;
549             }
550         }
551     } while (pBuffer);
552 
553     return (pBuffer);
554 }
555 
556 /*
557  *  ======== Transfer all buffers marked as finished from one list to another ========
558  */
RCL_Handler_BLE_CS_transferFinishedBuffers(List_List * pSrc,List_List * pDst)559 static bool RCL_Handler_BLE_CS_transferFinishedBuffers(List_List *pSrc, List_List *pDst)
560 {
561     /* Initialize return value */
562     bool callbackEvent = false;
563     RCL_MultiBuffer *pBuffer = NULL;
564 
565     /* Transfer the used buffers */
566     do
567     {
568         pBuffer = RCL_MultiBuffer_head(pSrc);
569 
570         if (pBuffer && (pBuffer->state == RCL_BufferStateFinished))
571         {
572             /* Pop from list and add to done list */
573             RCL_MultiBuffer *pBuff = RCL_MultiBuffer_get(pSrc);
574             RCL_MultiBuffer_put(pDst, pBuff);
575 
576             /* Trigger callback side effect*/
577             callbackEvent = true;
578         }
579         else
580         {
581             break;
582         }
583     } while (pBuffer);
584 
585     return (callbackEvent);
586 }
587 
588 /*
589  *  ======== Configure the BUFRAM size and interrupts for BLE CS ========
590  */
RCL_Handler_BLE_CS_configureTxRxFifo(RCL_CmdBleCs * pCmd)591 static void RCL_Handler_BLE_CS_configureTxRxFifo(RCL_CmdBleCs* pCmd)
592 {
593     /* Override the FIFO location and size */
594     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG1) = BLE_CS_TXFIFO_BASE_ADDR;
595     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG2) = BLE_CS_TXFIFO_LEN;
596     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG3) = BLE_CS_RXFIFO_BASE_ADDR;
597     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG4) = BLE_CS_RXFIFO_LEN;
598 
599     /* Reset FIFOs to have a clean start */
600     /* Writing to FCMD is safe since the PBE is not running, ref. RCL-367 */
601     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_FCMD) = LRFDPBE_FCMD_DATA_FIFO_RESET;
602 
603     /* Calculate how many entries can be stored simultaneous in given size of tx/rx fifos */
604     uint16_t nStepsFit = HWREG_READ_LRF(LRFDPBE_BASE + LRFDPBE_O_TXFWRITABLE) / sizeof(RCL_CmdBleCs_Step_Internal);
605     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_TXFWBTHRS) = (nStepsFit - 1) * sizeof(RCL_CmdBleCs_Step_Internal);
606 
607     uint16_t nResultsFit = HWREG_READ_LRF(LRFDPBE_BASE + LRFDPBE_O_RXFWRITABLE) / sizeof(RCL_CmdBleCs_StepResult_Internal);
608     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_RXFRBTHRS) = (nResultsFit - 1) * sizeof(RCL_CmdBleCs_StepResult_Internal);
609 
610     #ifndef PG2
611     /* CDDS BUG00003 - Temporarily workaround */
612     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_RXFRBTHRS) = sizeof(RCL_CmdBleCs_StepResult_Internal);
613     #endif
614 
615     /* FIFO pointers should auto-commit/auto-dealloc, enable threshold events */
616     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG0)   = HWREG_READ_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG0) | (LRFDPBE_FCFG0_TXACOM_M | LRFDPBE_FCFG0_TXADEAL_M | LRFDPBE_FCFG0_RXACOM_M | LRFDPBE_FCFG0_RXADEAL_M);
617     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG0)   = HWREG_READ_LRF(LRFDPBE_BASE + LRFDPBE_O_FCFG0) & (~(LRFDPBE_FCFG0_RXIRQMET_M | LRFDPBE_FCFG0_TXIRQMET_M));
618 
619     /* Clear any interrupts left from uninitialized fifos */
620     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_EVTCLR1)  =  (LRFDPBE_EVTCLR1_RXRDBTHR_M |  LRFDPBE_EVTCLR1_RXWRBTHR_M | LRFDPBE_EVTCLR1_TXRDBTHR_M | LRFDPBE_EVTCLR1_TXWRBTHR_M);
621     HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) | (LRFDDBELL_ICLR0_RXFIFO_M | LRFDDBELL_ICLR0_TXFIFO_M);
622 }
623 
624 /*
625  *  ======== Fill the BLE CS step descriptors into the BUFRAM TX FIFO ========
626  */
RCL_Handler_BLE_CS_preFillTxBuffer(RCL_CmdBleCs * pCmd)627 static RCL_Events RCL_Handler_BLE_CS_preFillTxBuffer(RCL_CmdBleCs* pCmd)
628 {
629     /* Initialize return value */
630     RCL_Events events = {.value = 0};
631 
632     /* Calculate how many additional step will fit (which might be all) */
633     uint16_t nWritable  = HWREG_READ_LRF(LRFDPBE_BASE + LRFDPBE_O_TXFWRITABLE) / sizeof(RCL_CmdBleCs_Step_Internal);
634     uint16_t nRemaining = (pCmd->mode.repeatSteps) ? (pCmd->mode.nSteps) : (pCmd->mode.nSteps - pCmd->stats->nStepsWritten);
635     uint16_t nBatch     = (nWritable < nRemaining) ? nWritable : nRemaining;
636 
637     /* Limited time is available when we start the command (ABS_START_TIME_OFFSET),
638         so the first batch is reduced */
639     if (pCmd->stats->nStepsWritten == 0)
640     {
641         nBatch = (nBatch < BLE_CS_FIRST_BATCH_SIZE) ? nBatch : BLE_CS_FIRST_BATCH_SIZE;
642     }
643 
644     /* Transfer the calculated number of steps into the fifo */
645     for (uint16_t i=0; i<nBatch; i++)
646     {
647         RCL_Handler_BLE_CS_fetchAndforwardNextStep(pCmd);
648     }
649 
650     /* Transfer the used buffers, should trigger a callback if any */
651     events.txBufferFinished = (uint32_t) RCL_Handler_BLE_CS_transferFinishedBuffers(&pCmd->stepBuffers, &pCmd->stepBuffersDone);
652 
653     return (events);
654 }
655 
656 /*
657  *  ======== Write the BLE CS Steps to the BUFRAM TX fifo ========
658  */
RCL_Handler_BLE_CS_fetchAndforwardNextStep(RCL_CmdBleCs * pCmd)659 static void RCL_Handler_BLE_CS_fetchAndforwardNextStep(RCL_CmdBleCs* pCmd)
660 {
661     /* Default return value */
662     RCL_CmdBleCs_Step *pStep = NULL;
663 
664     /* Buffers are served on a FIFO basis */
665     RCL_MultiBuffer *pStepBuffer = RCL_MultiBuffer_head(&pCmd->stepBuffers);
666 
667     /* Handle buffer boundaries within a batch */
668     pStepBuffer = RCL_MultiBuffer_findFirstWritableBuffer(pStepBuffer);
669     if (pStepBuffer)
670     {
671         /* Flag the buffer */
672         pStepBuffer->state = RCL_BufferStateInUse;
673 
674         /* Point to the beginning of step list */
675         pStep = (RCL_CmdBleCs_Step *) &pStepBuffer->data[0];
676 
677         /* Verify that there is enough bytes in the buffer */
678         if ((pStepBuffer->headIndex + sizeof(RCL_CmdBleCs_Step)) <= pStepBuffer->tailIndex)
679         {
680             /* Point to the next entry */
681             pStep += pStepBuffer->headIndex/sizeof(RCL_CmdBleCs_Step);
682 
683             /* Decompress and calculate internal parameters on step */
684             RCL_Handler_BLE_CS_preprocessStep(pCmd, pStep, &step);
685 
686             /* Send it to PBE */
687             uint32_t *ptr = (uint32_t *) &step;
688             for(uint8_t j=0; j<sizeof(RCL_CmdBleCs_Step_Internal)/sizeof(uint32_t); j++)
689             {
690                 HWREG_WRITE_LRF(LRFDTXF_BASE + LRFDTXF_O_TXD) = *(ptr + j);
691             }
692 
693             /* The step have been consumed */
694             pCmd->stats->nStepsWritten++;
695             pStepBuffer->headIndex += sizeof(RCL_CmdBleCs_Step);
696 
697             /* This buffer is exhausted, or end of subevent */
698             if (pStepBuffer->headIndex == pStepBuffer->tailIndex)
699             {
700                 if (pCmd->mode.repeatSteps == false)
701                 {
702                     /* Update state and move the buffer */
703                     pStepBuffer->state = RCL_BufferStateFinished;
704                 }
705                 else
706                 {
707                     /* Pretend that this is the beginning of the sequence */
708                     pStepBuffer->headIndex = 0;
709                     pCmd->stats->nStepsWritten = 0;
710                 }
711             }
712         }
713     }
714 }
715 
716 /*
717  *  ======== Read the BLE CS Step results from the BUFRAM RX fifo ========
718  */
RCL_Handler_BLE_CS_retrieveAndStoreNextResult(RCL_CmdBleCs * pCmd,bool forceBufferToFinishState)719 static void RCL_Handler_BLE_CS_retrieveAndStoreNextResult(RCL_CmdBleCs* pCmd, bool forceBufferToFinishState)
720 {
721     uint32_t *ptr = (uint32_t *) &result;
722     for(uint8_t j=0; j<sizeof(RCL_CmdBleCs_StepResult_Internal)/sizeof(uint32_t); j++)
723     {
724         *(ptr+j) = HWREG_READ_LRF(LRFDRXF_BASE + LRFDRXF_O_RXD);
725     }
726 
727     if (result.pktResult == RCL_CmdBleCs_PacketResult_Ok)
728     {
729         pCmd->stats->nRxOk += 1;
730     }
731     else
732     {
733         pCmd->stats->nRxNok += 1;
734     }
735 
736     /* Pop and fill the next container */
737     RCL_CmdBleCs_StepResult_Internal *pResult = RCL_Handler_BLE_CS_fetchNextStepResult(pCmd);
738     if (pResult)
739     {
740         memcpy(pResult, (RCL_CmdBleCs_StepResult_Internal *) &result, sizeof(RCL_CmdBleCs_StepResult_Internal));
741     }
742 
743     /* Identify HCI compression size */
744     uint16_t requiredSpaceInBytes = RCL_Handler_BLE_CS_estimateStepResultLength(pCmd, (RCL_CmdBleCs_StepResult_Internal *) &result);
745 
746     /* Alternative HCI destination */
747     RCL_MultiBuffer *pResultBuffer = RCL_Handler_BLE_CS_findBufferFitNumberOfBytes(&pCmd->resultBuffers, requiredSpaceInBytes);
748 
749     /* Increment if either internal or HCI format is used */
750     if (pResult || pResultBuffer)
751     {
752         pCmd->stats->nResultsRead++;
753     }
754 
755     /* Avoid NULL pointer dereferencing */
756     if (pResultBuffer)
757     {
758         /* Decode the start of the segment */
759         RCL_CmdBleCs_SubeventResults *pSubeventResults = (RCL_CmdBleCs_SubeventResults *) pResultBuffer->data;
760 
761         /* Initialize header in an empty buffer */
762         if (pResultBuffer->tailIndex == 0)
763         {
764             /* No steps reported yet */
765             pSubeventResults->numStepsReported = 0;
766 
767             /* Increment tail with header length */
768             RCL_MultiBuffer_commitBytes(pResultBuffer, sizeof(RCL_CmdBleCs_SubeventResults));
769         }
770 
771         /* Update the HCI header */
772         pSubeventResults->numStepsReported     += 1;
773         pSubeventResults->numAntennaPath        = pCmd->stats->numAntennaPath + 1;
774         pSubeventResults->referencePowerLevel   = result.gain;
775         pSubeventResults->frequencyCompensation = RCL_Handler_BLE_CS_convertFreqOffset(HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFCOMP) << 2);
776 
777         if (pCmd->stats->nResultsRead == 1)
778         {
779             pCmd->stats->reserved0 = result.gain;
780         }
781 
782         /* Decode the offset of data field */
783         uint8_t *pResult = RCL_MultiBuffer_getNextWritableByte(pResultBuffer);
784 
785         /* Compress and write the data */
786         uint32_t nBytes = RCL_Handler_BLE_CS_convertStepResult(pCmd, pResult, (RCL_CmdBleCs_StepResult_Internal *) &result);
787 
788         /* Commit the pointers in the buffer */
789         RCL_MultiBuffer_commitBytes(pResultBuffer, nBytes);
790 
791         /* Force close the multibuffer, even if there is more space left */
792         if ( (pCmd->mode.repeatSteps == false) && (pCmd->mode.nSteps == pCmd->stats->nResultsRead) )
793         {
794             pResultBuffer->state = RCL_BufferStateFinished;
795         }
796         else if (forceBufferToFinishState)
797         {
798             pResultBuffer->state = RCL_BufferStateFinished;
799         }
800     }
801 }
802 
803 /*
804  *  ======== Read the BLE CS Step results from the BUFRAM RX fifo ========
805  */
RCL_Handler_BLE_CS_readWriteBuffer(RCL_CmdBleCs * pCmd,bool forceBufferToFinishState)806 static RCL_Events RCL_Handler_BLE_CS_readWriteBuffer(RCL_CmdBleCs* pCmd, bool forceBufferToFinishState)
807 {
808     /* Initialize return value */
809     RCL_Events events = {.value = 0};
810 
811     /* Calculate how many result entries are available in rx fifo (might be all that has left) */
812     uint16_t nBatch  = HWREG_READ_LRF(LRFDPBE_BASE + LRFDPBE_O_RXFREADABLE) / sizeof(RCL_CmdBleCs_StepResult_Internal);
813 
814     /* Read out the calculated number of entries */
815     for (uint16_t i=0; i<nBatch; i++)
816     {
817         /* Retrieve all that's available and terminate*/
818         bool forceTerminate = (forceBufferToFinishState && (i == nBatch-1));
819 
820         RCL_Handler_BLE_CS_retrieveAndStoreNextResult(pCmd, forceTerminate);
821         RCL_Handler_BLE_CS_fetchAndforwardNextStep(pCmd);
822     }
823 
824     /* Transfer the used buffers, should trigger a callback if any */
825     events.rxBufferFinished = (uint32_t) RCL_Handler_BLE_CS_transferFinishedBuffers(&pCmd->resultBuffers, &pCmd->resultBuffersDone);
826     events.txBufferFinished = (uint32_t) RCL_Handler_BLE_CS_transferFinishedBuffers(&pCmd->stepBuffers, &pCmd->stepBuffersDone);
827 
828     /* Reduce the batch size if there is only a few entries missing */
829     int16_t nRemaining = pCmd->mode.nSteps - pCmd->stats->nResultsRead;
830     if (nRemaining <= 0)
831     {
832         if (pCmd->mode.repeatSteps == false)
833         {
834             /* No more results expected, set the threshold to the max */
835             HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_RXFRBTHRS) = 0x3FF;
836         }
837     }
838     else if (nRemaining < nBatch)
839     {
840         /* Reduce the Fifo threshold to number of remaining steps */
841         HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_RXFRBTHRS) = (nRemaining * sizeof(RCL_CmdBleCs_StepResult_Internal));
842     }
843 
844     return (events);
845 }
846 
847 
848 /*
849  *  ======== Initialize the S2R engine ========
850  */
RCL_Handler_BLE_CS_configureS2R(RCL_CmdBleCs * pCmd)851 static void RCL_Handler_BLE_CS_configureS2R(RCL_CmdBleCs *pCmd)
852 {
853     LRF_setRclClockEnable(LRFDDBELL_CLKCTL_S2RRAM_M | LRFDDBELL_CLKCTL_S2R_M);
854 
855     /* Access the list of multibuffers */
856     RCL_MultiBuffer *pS2rBuffer = RCL_MultiBuffer_head(&pCmd->s2rBuffers);
857 
858     /* Only set up S2R, if there is buffer on the list */
859     if (pS2rBuffer)
860     {
861         /* Store 32bit words in S2R (offset 3072) memory; don't arm yet */
862         HWREG_WRITE_LRF(LRFDS2R_BASE + LRFDS2R_O_START) = BLE_CS_S2R_MEMORY_OFFSET;
863         HWREG_WRITE_LRF(LRFDS2R_BASE + LRFDS2R_O_STOP)  = HWREG_READ_LRF(LRFDS2R_BASE + LRFDS2R_O_START) + (RCL_BLE_CS_MAX_S2R_LEN >> pCmd->mode.phy);
864         HWREG_WRITE_LRF(LRFDS2R_BASE + LRFDS2R_O_CFG)   = LRFDS2R_CFG_CTL_EN
865                                                         | LRFDS2R_CFG_SEL_FRONTEND
866                                                         | LRFDS2R_CFG_TRIGMODE_ONESHOT
867                                                         | LRFDS2R_CFG_LAST0_DIS;
868     }
869 }
870 
871 /*
872  *  ======== Read the S2R memory ========
873  */
RCL_Handler_BLE_CS_readS2RSamples(RCL_CmdBleCs * pCmd)874 RCL_Events RCL_Handler_BLE_CS_readS2RSamples(RCL_CmdBleCs *pCmd)
875 {
876     RCL_Events events = {.value = 0};
877 
878     uint16_t s2rLength  = sizeof(S2RSample) * HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTWORDSIZE);
879     uint16_t dataLength = sizeof(RCL_CmdBleCs_S2r) + s2rLength;
880 
881     /* Access the list of multibuffers */
882     RCL_MultiBuffer *pS2rBuffer = RCL_Handler_BLE_CS_findBufferFitNumberOfBytes(&pCmd->s2rBuffers, dataLength);
883 
884     if (pS2rBuffer)
885     {
886         /* Decode the next free slot in the multibuffer */
887         RCL_CmdBleCs_S2r *pS2rData = (RCL_CmdBleCs_S2r *) RCL_MultiBuffer_getNextWritableByte(pS2rBuffer);
888 
889         /* Store the step index */
890         pS2rData->phy        = pCmd->mode.phy;
891         pS2rData->idx        = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTIDX);
892         pS2rData->channel    = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTCHIDX);
893         pS2rData->payloadLen = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTPAYLOADLEN);
894         /* 32 bit access */
895         pS2rData->payload0   = HWREG_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTPAYLOAD0L);
896         pS2rData->payload1   = HWREG_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTPAYLOAD1L);
897         pS2rData->payload2   = HWREG_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTPAYLOAD2L);
898         pS2rData->payload3   = HWREG_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTPAYLOAD3L);
899 
900         /* Number of valid samples to be copied out with 32bit operation
901         Need to calculate with 0/32/64/96/128 bit @ 8MHz/4MHz front-end sampling */
902         pS2rData->iqLength = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_S2ROUTWORDSIZE);
903 
904         /* Store the data, unwrap the loop for faster copying */
905         uint32_t *src = (uint32_t *)S2R_RAM_BASE_ADDR;
906         uint32_t *dst = (uint32_t *)&pS2rData->data;
907 
908         #ifdef NO_INLINE_ASM
909             for(uint16_t i=0; i<(pS2rData->iqLength >> 3); i++)
910             {
911                 *dst++ = *src++;
912                 *dst++ = *src++;
913                 *dst++ = *src++;
914                 *dst++ = *src++;
915                 *dst++ = *src++;
916                 *dst++ = *src++;
917                 *dst++ = *src++;
918                 *dst++ = *src++;
919             }
920         #else
921             for(uint16_t i=0; i<(pS2rData->iqLength >> 2); i++)
922             {
923                 __asm(
924                 "LDMIA %0!, {r4, r5, r6, r7} \n"
925                 "STMIA %1!, {r4, r5, r6, r7} \n"
926                 : "+r" (src), "+r" (dst) :
927                 : "r4", "r5", "r6", "r7");
928             }
929         #endif
930 
931         /* Flag the entry */
932         RCL_MultiBuffer_commitBytes(pS2rBuffer, dataLength);
933         pCmd->stats->nS2RDone++;
934 
935         /* Force close the buffer, even if there is more space left */
936         pS2rBuffer->state = RCL_BufferStateFinished;
937 
938         /* Transfer the used buffers, should trigger a callback if any */
939         events.swTriggered = (uint32_t) RCL_Handler_BLE_CS_transferFinishedBuffers(&pCmd->s2rBuffers, &pCmd->s2rBuffersDone);
940     }
941 
942     return (events);
943 }
944 
945 /*
946  *  ======== Read the statistics from the PBE ========
947  */
RCL_Handler_BLE_CS_readStatistics(RCL_CmdBleCs * pCmd)948 static void RCL_Handler_BLE_CS_readStatistics(RCL_CmdBleCs *pCmd)
949 {
950     if (pCmd->stats)
951     {
952         pCmd->stats->nStepsDone = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_NSTEPSDONE);
953         pCmd->stats->lastRssi   = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_RSSILAST);
954         pCmd->stats->lastFoff   = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFLAST);
955         pCmd->stats->foffComp   = HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFCOMP);
956     }
957 }
958 
959 /*
960  *  ======== Load the command and step descriptors into LRF REGISTERS/BUFRAM ========
961  */
RCL_Handler_BLE_CS_preprocessCommand(RCL_CmdBleCs * pCmd)962 static void RCL_Handler_BLE_CS_preprocessCommand(RCL_CmdBleCs *pCmd)
963 {
964     /* Force antenna switching time to zero for single antenna path per spec */
965     if (pCmd->antennaConfig.select == 0)
966     {
967         pCmd->timing.tSw = 0;
968     }
969 
970     /* Decode mapping of configuration to antennas */
971     const RCL_AntennaConfig_t *antennaEntry = &antennaConfig[pCmd->antennaConfig.select];
972 
973     /* Decode the Phy specific settings */
974     const RCL_PhyConfig_t *config = &phyConfigLut[pCmd->mode.phy];
975 
976     /* Clear output statistics */
977     if (pCmd->stats)
978     {
979         memset((void *)pCmd->stats, 0, sizeof(RCL_CmdBleCs_Stats));
980 
981         pCmd->stats->lastRssi = LRF_RSSI_INVALID;
982         pCmd->stats->numAntennaPath = antennaEntry->numPath;
983     }
984 
985     /* Mode */
986     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_MODE) = ((pCmd->mode.role        << PBE_BLE_CS_RAM_MODE_ROLE_S)      & PBE_BLE_CS_RAM_MODE_ROLE_M) |
987                                                                  ((pCmd->mode.phy         << PBE_BLE_CS_RAM_MODE_PHY_S)       & PBE_BLE_CS_RAM_MODE_PHY_M) |
988                                                                  ((pCmd->mode.repeatSteps << PBE_BLE_CS_RAM_MODE_INFINIT_S)   & PBE_BLE_CS_RAM_MODE_INFINIT_M) |
989                                                                  ((pCmd->mode.nSteps      << PBE_BLE_CS_RAM_MODE_NUM_STEPS_S) & PBE_BLE_CS_RAM_MODE_NUM_STEPS_M);
990 
991     /* Antenna */
992     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_ANTN)   = antennaEntry->numPath;
993     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_ANTMSK) = pCmd->antennaConfig.gpoMask;
994     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_ANT0)   = pCmd->antennaConfig.gpoVal[0];
995     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_ANT1)   = pCmd->antennaConfig.gpoVal[1];
996     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_ANT2)   = pCmd->antennaConfig.gpoVal[2];
997     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_ANT3)   = pCmd->antennaConfig.gpoVal[3];
998 
999     /* Timing */
1000     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TFCS)        = pCmd->timing.tFcs - (TPLT + config->tStartup); // Pilot tone + startup time is included into the TFCS budget
1001     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TFM)         = pCmd->timing.tFm;
1002     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TPM)         = pCmd->timing.tPm;
1003     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TIP1)        = pCmd->timing.tIp1;
1004     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TIP2)        = pCmd->timing.tIp2;
1005     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSW)         = pCmd->timing.tSw;
1006     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSWADJA)     = pCmd->timing.tSwAdjustA;
1007     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSWADJB)     = pCmd->timing.tSwAdjustB;
1008 
1009     /* Timegrid adjustment shall be initialized with maximum unsigned value (ca. 536s @ 4MHz) */
1010     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSTEPACCTHRH)= 0x7FFF;
1011     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSTEPACCTHRL)= 0xFFFF;
1012     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSTEPACCH)   = 0;
1013     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSTEPACCL)   = 0;
1014     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSTEPCOMP)   = 0;
1015 
1016     /* Initialize MOD.FOFF values. Usueful for sub-events without mode 0 steps */
1017     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFSUM)     = 0;
1018     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFNUM)     = 0;
1019     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_RSSILAST)    = LRF_RSSI_INVALID;
1020     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_RSSISUM0)    = 0;
1021     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_RSSINUM0)    = 0;
1022     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_NSTEPSDONE)  = 0;
1023 
1024     /* Apply override if configured */
1025     if (pCmd->frontend.foffOverrideEnable)
1026     {
1027         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFSUM) = pCmd->frontend.foffOverride;
1028         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFNUM) = (1 << 15) | 1; // [15]=Enable, [1]=NUM hardcoded to 1
1029     }
1030 
1031     /* Program frequency dependent config: hardcode on 2440MHz, to be updated on the fly */
1032     HWREG_WRITE_LRF(LRFDMDM32_BASE + LRFDMDM32_O_DEMFRAC1_DEMFRAC0) = 0x0D800000;     // P: Constant
1033     HWREG_WRITE_LRF(LRFDMDM32_BASE + LRFDMDM32_O_DEMFRAC3_DEMFRAC2) = 0x0E4C0000;     // Q: Being dynammically scaled by RFE per channel
1034 
1035     /* Shaper gain */
1036     HWREG_WRITE_LRF(LRFDRFE_BASE + LRFDRFE_O_MOD0) = 0x1824;
1037 
1038     /* Configure AGC with gain=15/7 or a static value=gain/gain */
1039     uint16_t rxGain = pCmd->frontend.rxGain;
1040     HWREG_WRITE_LRF(LRFDRFE_BASE + LRFDRFE_O_SPARE0) = (rxGain == 0)
1041                                                      ? (0x30F7)
1042                                                      : ((rxGain << 4) | rxGain);
1043 
1044     uint8_t lutIdx = RCL_CmdBleCs_Tpm_40us;
1045     if (pCmd->timing.tPm <= RCL_BLE_CS_US_TO_MCE_TIMER(20))
1046     {
1047         lutIdx = RCL_CmdBleCs_Tpm_20us;
1048     }
1049     if (pCmd->timing.tPm <= RCL_BLE_CS_US_TO_MCE_TIMER(10))
1050     {
1051         lutIdx = RCL_CmdBleCs_Tpm_10us;
1052     }
1053 
1054     /* MAFC gain */
1055     #ifdef DeviceFamily_CC27XX
1056         /* Workaround for IQ swap */
1057         HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_DEMMISC2) = config->demmisc2 | LRFDMDM_DEMMISC2_PDIFIQCONJEN;
1058     #else
1059         HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_DEMMISC2) = config->demmisc2;
1060     #endif
1061 
1062     /* Channel filter = 0.33 */
1063     HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_DEMMISC1) = 0x0001;
1064 
1065     /* Fife IIR adaptation rate = 64 (provides good mode-0 frequency tolerance for both PHYs) */
1066     HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_DEMFIFE0) = 0x0007;
1067 
1068     /* Use precalibration values or mode-0 estimates */
1069     if ((pCmd->precalTable) && (pCmd->precalTable->valid))
1070     {
1071         HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_SPARE1) = (1<<8);
1072     }
1073     else
1074     {
1075         HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_SPARE1) = 0;
1076     }
1077 
1078     /* Baudrate specific settings */
1079     HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_SPARE0)                        = config->pctConfig[lutIdx].val;
1080     HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_BAUD)                          = config->baud;
1081     HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_MODSYMMAP0)                    = config->symmap;
1082     HWREG_WRITE_LRF(LRFDRFE_BASE + LRFDRFE_O_SPARE3)                        = config->magnConfig[lutIdx].val;
1083     HWREG_WRITE_LRF(LRFDRFE_BASE + LRFDRFE_O_RSSIOFFSET)                    = config->rssioffset;
1084     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_DEMMISC3)          = config->demmisc3;
1085     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TPOSTPROCESSDIV1)  = config->tPostProcessDiv1;
1086     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TPOSTPROCESSDIV12) = config->tPostProcessDiv12;
1087     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TRXTIMEOUTI0)      = config->tRxTimeoutI0;
1088     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TRXTIMEOUTI3)      = config->tRxTimeoutI3;
1089     HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TPILOTADJ)         = config->tPilotAdjust;
1090 
1091     /* Alias for dynamic parameters for calculations */
1092     uint16_t tIp1  = pCmd->timing.tIp1;
1093     uint16_t tIp2  = pCmd->timing.tIp2;
1094     uint16_t tFm   = pCmd->timing.tFm;
1095     uint16_t tPm   = pCmd->timing.tPm;
1096     uint16_t tFcs  = pCmd->timing.tFcs;
1097     uint16_t tSw   = pCmd->timing.tSw;
1098     uint16_t nPath = antennaEntry->numPath;
1099 
1100     /* Phy specific delays */
1101     uint16_t tStartup    = config->tStartup;
1102     uint16_t tPkt        = config->tPacket;
1103     uint16_t tCorr       = config->tCorr;
1104     uint16_t tDem        = config->tDem;
1105     uint16_t tTr         = config->tTr;
1106     uint16_t tFidc       = config->tFidc;
1107     uint16_t tTxModDelay = config->tTxModDelay;
1108     uint16_t tInfiniteRx = config->tInfiniteRx;
1109 
1110     /* Modulation + Demodulation delay for timestamp capturing */
1111     uint16_t tTimestampDelay1 = config->tTimestampDelay1;
1112     uint16_t tTimestampDelay3 = config->tTimestampDelay3;
1113 
1114     /* Calculate base terms of step duration for each mode.
1115        Later can be extended with optional payload per step before sending it over to the PBE. */
1116     tStepLut[RCL_CmdBleCs_StepMode_0] = (tFcs + ((tPkt + TRD) << 1) + TGD + tIp1 + tFm);
1117     tStepLut[RCL_CmdBleCs_StepMode_1] = (tFcs + ((tPkt + TPYL + TRD) << 1) + tIp1);
1118     tStepLut[RCL_CmdBleCs_StepMode_2] = (tFcs + ((((tPm + tSw) * (nPath + 1)) + TRD) << 1) + tIp2);
1119     tStepLut[RCL_CmdBleCs_StepMode_3] = (tFcs + ((tPkt + TPYL + TGD + ((tPm + tSw) * (nPath + 1)) + TRD) << 1) + tIp2);
1120 
1121     /* Adjustment of MCE timegrid */
1122     const RCL_Tadjust_t *tAdj = &config->tAdj[pCmd->mode.role];
1123 
1124     if (pCmd->mode.role == RCL_CmdBleCs_Role_Initiator)
1125     {
1126         /* Calculate base terms of interlude period. Later will scale with payload. */
1127 
1128         /* TX */
1129         tAdjALut[RCL_CmdBleCs_StepMode_0] = tAdj->mode0[0] + 0xFFFF;
1130         tAdjALut[RCL_CmdBleCs_StepMode_1] = tAdj->mode1[0] + 0xFFFF;
1131         tAdjALut[RCL_CmdBleCs_StepMode_2] = tAdj->mode2[0] + 0x0000; // No packet, variable used for pilot adjustment
1132         tAdjALut[RCL_CmdBleCs_StepMode_3] = tAdj->mode3[0] + 0xFFFF;
1133 
1134         /* RX */
1135         tAdjBLut[RCL_CmdBleCs_StepMode_0] = tAdj->mode0[1] + TRD + tIp1 - TPLT;
1136         tAdjBLut[RCL_CmdBleCs_StepMode_1] = tAdj->mode1[1] + TRD + tIp1 - TPLT;
1137         tAdjBLut[RCL_CmdBleCs_StepMode_2] = tAdj->mode2[1] + TRD + tIp2 + tSw + tFidc;
1138         tAdjBLut[RCL_CmdBleCs_StepMode_3] = tAdj->mode3[1] + TRD + tIp2 + tSw + tFidc;
1139 
1140         /* ToAD common term */
1141         tRttAdjustLut[RCL_CmdBleCs_StepMode_0] = 0; /* NA, no RTT defined */
1142         tRttAdjustLut[RCL_CmdBleCs_StepMode_1] = TPYL + TRD + tIp1 + tPkt + tTimestampDelay1;
1143         tRttAdjustLut[RCL_CmdBleCs_StepMode_2] = 0; /* NA, no RTT defined */
1144         tRttAdjustLut[RCL_CmdBleCs_StepMode_3] = TPYL + (TGD << 1) + (((tPm + tSw) * ((nPath << 1) + 1))) + TRD + tIp2 + tPkt + tTimestampDelay3;
1145 
1146         /* Initiator: timeout is hardcoded in the MCE in order to comply with the static timegrid.
1147            This parameter is therefor ignored.  */
1148         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TRXTIMEOUTR013)   = 0;
1149         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TRXWIDENINGR0)    = 0;
1150         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSTEPREMAININGR0) = 0;
1151     }
1152     else
1153     {
1154         /* RX */
1155         tAdjALut[RCL_CmdBleCs_StepMode_0] = tAdj->mode0[0] - tCorr + tTr + TRD + tIp1 - TPLT - tTxModDelay;
1156         tAdjALut[RCL_CmdBleCs_StepMode_1] = tAdj->mode1[0] - tCorr + tTr + TRD + tIp1 - TPLT - tTxModDelay;
1157         tAdjALut[RCL_CmdBleCs_StepMode_2] = tAdj->mode2[0] + tStartup + TPLT + tSw + tFidc;
1158         tAdjALut[RCL_CmdBleCs_StepMode_3] = tAdj->mode3[0] - tCorr + tTr + TGD + tSw + tFidc;
1159 
1160         /* TX */
1161         tAdjBLut[RCL_CmdBleCs_StepMode_0] = tAdj->mode0[1];
1162         tAdjBLut[RCL_CmdBleCs_StepMode_1] = tAdj->mode1[1];
1163         tAdjBLut[RCL_CmdBleCs_StepMode_2] = tAdj->mode2[1] - tFidc - tSw /* + TRD */ + tIp2 - TPLT; // Ramp-down delay is added by the topSM
1164         tAdjBLut[RCL_CmdBleCs_StepMode_3] = tAdj->mode3[1] - tFidc - tSw /* + TRD */ + tIp2 - TPLT - tTxModDelay;
1165 
1166         /* ToAD common term */
1167         tRttAdjustLut[RCL_CmdBleCs_StepMode_0] = 0; /* NA, no RTT defined */
1168         tRttAdjustLut[RCL_CmdBleCs_StepMode_1] = TPYL + TRD + tIp1 + tPkt - tTimestampDelay1;
1169         tRttAdjustLut[RCL_CmdBleCs_StepMode_2] = 0; /* NA, no RTT defined */
1170         tRttAdjustLut[RCL_CmdBleCs_StepMode_3] = TPYL + (TGD << 1) + (((tPm + tSw) * ((nPath << 1) + 1))) + TRD + tIp2 + tPkt - tTimestampDelay3;
1171 
1172         /* The miminum value is defined by the static timegrid. Different for each datarate and implemented by the MCE. */
1173         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TRXTIMEOUTR013) = config->tRxTimeoutRn;
1174 
1175         /* Handle infinite/extended RX timeout implemented by PBE */
1176         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TRXWIDENINGR0)
1177             = (pCmd->timing.tRxWideningR0 == 0xFFFF)
1178             ? (0xFFFF)
1179             : RCL_BLE_CS_MCE_TIMER_TO_PBE_TIMER(tFcs + (tPkt - tTr) + tDem + T3US + pCmd->timing.tRxWideningR0);
1180 
1181         HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_TSTEPREMAININGR0) =
1182           RCL_BLE_CS_MCE_TIMER_TO_PBE_TIMER(0 - tDem + tTr + TRD + tIp1 + tPkt + TGD + tFm + TRD - tInfiniteRx);
1183     }
1184 
1185     /* Adjustment of antenna control per mode per phy */
1186     const RCL_Tadjust_t *tAnt = &config->tAnt[pCmd->mode.role & 1];
1187 
1188     tAntALut[RCL_CmdBleCs_StepMode_0] = 0; /* NA - no antenna */
1189     tAntALut[RCL_CmdBleCs_StepMode_1] = 0; /* NA - no antenna */
1190     tAntALut[RCL_CmdBleCs_StepMode_2] = tAnt->mode2[0] + TPLT;
1191     tAntALut[RCL_CmdBleCs_StepMode_3] = tAnt->mode3[0] + TPLT + tPkt + TGD;
1192 
1193     tAntBLut[RCL_CmdBleCs_StepMode_0] = 0; /* NA - no antenna */
1194     tAntBLut[RCL_CmdBleCs_StepMode_1] = 0; /* NA - no antenna */
1195     tAntBLut[RCL_CmdBleCs_StepMode_2] = tAnt->mode2[1];
1196     tAntBLut[RCL_CmdBleCs_StepMode_3] = tAnt->mode3[1];
1197 
1198     /* Enforce modulator and demodulator clock. RTL bug with automatic control. */
1199     LRF_setRclClockEnable(LRFDDBELL_CLKCTL_DEM_M | LRFDDBELL_CLKCTL_MOD_M);
1200 }
1201 
1202 /*
1203  *  ======== Preprocess the step ========
1204  */
RCL_Handler_BLE_CS_preprocessStep(RCL_CmdBleCs * pCmd,RCL_CmdBleCs_Step * pStep,RCL_CmdBleCs_Step_Internal * pStepI)1205 static void RCL_Handler_BLE_CS_preprocessStep(RCL_CmdBleCs *pCmd, RCL_CmdBleCs_Step *pStep, RCL_CmdBleCs_Step_Internal *pStepI)
1206 {
1207     /* Decompress the HCI format into PBE internal format */
1208     pStepI->channelIdx     = pStep->channelIdx;
1209     pStepI->mode           = pStep->mode;
1210     pStepI->antennaPermIdx = pStep->antennaPermIdx;
1211     pStepI->toneExtension  = pStep->toneExtension;
1212     pStepI->payloadLen     = pStep->payloadLen;
1213     pStepI->aaTx           = pStep->aaTx;
1214     pStepI->aaRx           = pStep->aaRx;
1215 
1216     for (uint8_t i=0; i<RCL_BLE_CS_MAX_PAYLOAD_SIZE; i++)
1217     {
1218         pStepI->payloadTx[i] = pStep->payloadTx[i];
1219         pStepI->payloadRx[i] = pStep->payloadRx[i];
1220     }
1221 
1222     /* Disable restricted channels if filtering is turned on */
1223     if (pCmd->mode.chFilterEnable == true)
1224     {
1225         uint16_t channelIdx = pStepI->channelIdx;
1226 
1227         if (  channelIdx > BLE_CS_MAX_CHANNEL
1228            || channelIdx == 0  /* Advertisement frequency (channel 37)*/
1229            || channelIdx == 1
1230            || channelIdx == 23
1231            || channelIdx == 24 /* Advertisement frequency (channel 38)*/
1232            || channelIdx == 25
1233            || channelIdx == 77
1234            || channelIdx == 78 /* Advertisement frequency (channel 39)*/)
1235         {
1236             /* The user configured a channel outside the allowed domain or
1237                a restricted channel. Guard channels also covered!
1238                We still keep the timegrid but silence this step. */
1239             pStepI->channelIdx = BLE_CS_SILENT_CHANNEL;
1240         }
1241     }
1242 
1243     /* Decode the base term for the complete duration of the step */
1244     uint32_t tStep = tStepLut[pStepI->mode];
1245     uint16_t tAdjA = tAdjALut[pStepI->mode];
1246     uint16_t tAdjB = tAdjBLut[pStepI->mode];
1247 
1248     /* Scale with bit length and 1M/2M rate */
1249     uint16_t tPyl = (payloadLut[pStepI->payloadLen]) >> pCmd->mode.phy;
1250 
1251     /* Extend with timing of optional payload */
1252     if (pStepI->payloadLen)
1253     {
1254         /* Adjustment only on Reflector */
1255         uint16_t tAdj = (pCmd->mode.role == RCL_CmdBleCs_Role_Reflector)
1256                       ? (tPyl)
1257                       : (0);
1258 
1259         /* Payload is only allowed for certain modes. */
1260         if (pStepI->mode == RCL_CmdBleCs_StepMode_1 ||
1261             pStepI->mode == RCL_CmdBleCs_StepMode_3)
1262         {
1263             /* Multiplied by two for combined effect of TX and RX */
1264             tStep += (tPyl << 1);
1265 
1266             /* The duration from AA sync until the next activity scales with payload on reflector only */
1267             tAdjA += tAdj;
1268         }
1269         else
1270         {
1271             /* Enforce no payload for mode 0 & 2 */
1272             pStepI->payloadLen = 0;
1273 
1274             /* No adjustment needed */
1275             tPyl = 0;
1276         }
1277     }
1278 
1279     /* Configure the PBE with the scaled step duration */
1280     pStepI->tStep = (uint16_t) RCL_BLE_CS_MCE_TIMER_TO_PBE_TIMER(tStep);
1281 
1282     /* Configure the MCE with the scaled intermediate timegrid parameters */
1283     pStepI->tAdjustA = tAdjA;
1284     pStepI->tAdjustB = tAdjB;
1285 
1286     /* Antenna timing from beginning of step */
1287     pStepI->tAntennaA = tAntALut[pStepI->mode] + tPyl;
1288     pStepI->tAntennaB = tAntBLut[pStepI->mode];
1289 
1290     /* DC compensation */
1291     if ((pCmd->precalTable) && (pCmd->precalTable->valid))
1292     {
1293         pCmd->precalTable->callback(pCmd->precalTable, pStepI->channelIdx, (uint32_t *)&pStepI->dcComp[0], (uint32_t *)&pStepI->dcComp[1]);
1294     }
1295     else
1296     {
1297         pStepI->dcComp[0].i = 0;
1298         pStepI->dcComp[0].q = 0;
1299         pStepI->dcComp[1].i = 0;
1300         pStepI->dcComp[1].q = 0;
1301     }
1302 
1303     /* Antenna calculations */
1304     pStepI->antennaSequence = 0;
1305 
1306     /* Decode mapping of configuration to antennas */
1307     const RCL_AntennaConfig_t *antennaEntry = &antennaConfig[pCmd->antennaConfig.select];
1308 
1309     /*  Avoid indexing out of range */
1310     if (pStepI->antennaPermIdx < antennaEntry->numPerm)
1311     {
1312         /* Find the proper permutation pattern based on generic config and random step related selection.
1313             The same table is used, but we index the entries differently */
1314         uint8_t apn = antennaPermutation[pStepI->antennaPermIdx * antennaEntry->increment].apn;
1315 
1316         /* We reuse the same permutation table for 1:1, 1:N, N:1 and 2:2,
1317             but only use the appropriate number of entries from each row */
1318         for(uint8_t k1=0; k1<antennaEntry->numPath; k1++)
1319         {
1320             uint8_t apm = antennaEntry->ap[pCmd->mode.role & 1].apn;
1321 
1322             /* Decode bitfields */
1323             uint8_t k2 = DECODE_ANTENNA(apn, k1);
1324             uint8_t k3 = DECODE_ANTENNA(apm, k2);
1325 
1326             /* Antenna sequence is stored as [7:6]=A4, [5:4]=A3, [3:2]=A2, [1:0]=A1.
1327                 The PBE will decode it accordingly. */
1328             pStepI->antennaSequence |= ENCODE_ANTENNA(k3, k1);
1329         }
1330     }
1331 
1332     /* Look up the frequency offset actuation error (only used by mode 0) */
1333     pStepI->foffErr = (uint16_t) foffErrorLut[pStepI->channelIdx];
1334 }
1335 
1336 /*
1337  *  ======== Fetch the next available step result container in the list and return a pointer to it ========
1338  */
RCL_Handler_BLE_CS_fetchNextStepResult(RCL_CmdBleCs * pCmd)1339 static RCL_CmdBleCs_StepResult_Internal* RCL_Handler_BLE_CS_fetchNextStepResult(RCL_CmdBleCs *pCmd)
1340 {
1341     RCL_CmdBleCs_StepResult_Internal *pResult = NULL;
1342 
1343     if ((pCmd->stats->nResultsRead < pCmd->mode.nSteps) && pCmd->results)
1344     {
1345         pResult = &pCmd->results[pCmd->stats->nResultsRead];
1346     }
1347 
1348     return (pResult);
1349 }
1350 
1351 /*
1352  *  ======== RCL_Handler_BLE_CS_convertFreqOffset ========
1353  */
RCL_Handler_BLE_CS_convertFreqOffset(int16_t foffMeasured)1354 static int16_t RCL_Handler_BLE_CS_convertFreqOffset(int16_t foffMeasured)
1355 {
1356     /* Intermediate arithmetics on 32bit
1357        freqOffset = foff * 100 * 1e6 / 2^23
1358                   = foff * (100 * 1e6 / 2^7) / 2^16
1359                   = foff * 0xBEBC2 / 2^16 [0.01 ppm] */
1360     int32_t freqOffset = (int32_t)foffMeasured;
1361     freqOffset *= 0xBEBC2;
1362     freqOffset >>= 16;
1363 
1364     return (int16_t)(freqOffset);
1365 }
1366 
1367 /*
1368  *  ======== RCL_Handler_BLE_CS_convertRtt ========
1369  */
RCL_Handler_BLE_CS_convertRtt(RCL_CmdBleCs * pCmd,uint8_t mode,int8_t channel,int16_t foff,uint8_t payloadLen,bool secondToneExtensionSlot,float toAD,uint16_t corrBefore,uint16_t corrPeak,uint16_t corrAfter)1370 static int16_t RCL_Handler_BLE_CS_convertRtt(RCL_CmdBleCs *pCmd, uint8_t mode, int8_t channel, int16_t foff, uint8_t payloadLen, bool secondToneExtensionSlot,
1371                                              float toAD, uint16_t corrBefore, uint16_t corrPeak, uint16_t corrAfter)
1372 {
1373     /* Raw RTT need to be compensated with:
1374        - Correlator before/after fractional approximation
1375        - Nominal tunr-around time T = TSY + TIP + TEXT + TPYL + ...
1376        - Time drift due to XTAL offset (initiator only)
1377        - CMIX (channel specific) and layout related errors */
1378 
1379     /* Conversion from 4M/8M baudrate to 48M clock tick */
1380     uint8_t baud2tick = (pCmd->mode.phy) ? (6) : (12);
1381 
1382     /* Quadratic interpolation with correlator values */
1383     float corr = (float)(baud2tick * (corrBefore - corrAfter))
1384                / (float)((corrAfter << 1) + (corrBefore << 1) - (corrPeak << 2));
1385 
1386     /* Compensation applies with different sign */
1387     toAD += (pCmd->mode.role == RCL_CmdBleCs_Role_Initiator) ? (+corr) : (-corr);
1388 
1389     /* Remove nominal turn-around time (adjust to the signal on the antenna) */
1390     toAD -= tRttAdjustLut[mode];
1391 
1392     /* Adjust with optional payload duration */
1393     toAD -= (payloadLut[payloadLen] >> pCmd->mode.phy);
1394 
1395     /* Adjust with optional tone-extension slot for mode-3 */
1396     if (secondToneExtensionSlot == true)
1397     {
1398          toAD -= (pCmd->timing.tPm + pCmd->timing.tSw);
1399     }
1400 
1401     /* Adjust initiator */
1402     if (pCmd->mode.role == RCL_CmdBleCs_Role_Initiator)
1403     {
1404         /* XTAL offset related drift */
1405         //toAD *= 100e6/(100e6 + foff); //TODO: This takes to much execution time
1406     }
1407 
1408     /* Channel specific delays */
1409     #define CHANNEL_MID (float)(40.0)
1410     #define CHANNEL_CAL (float)(0.0415)
1411     float adj = CHANNEL_CAL * (channel - CHANNEL_MID);
1412     toAD -= (pCmd->mode.role == RCL_CmdBleCs_Role_Initiator) ? (-adj) : (+adj);
1413 
1414     /* Convert to 0.5ns units as per HCI spec requires */
1415     toAD *= (float)41.6666;
1416 
1417     /* Round */
1418     toAD += (float)0.5;
1419 
1420     /* Return the adjusted timeticks */
1421     return ((int16_t) toAD);
1422 }
1423 
1424 /*
1425  *  ======== RCL_Handler_BLE_CS_rotateVector ========
1426  */
RCL_Handler_BLE_CS_rotateVector(int16_t * pct_i,int16_t * pct_q,int16_t theta)1427 void RCL_Handler_BLE_CS_rotateVector(int16_t *pct_i, int16_t *pct_q, int16_t theta)
1428 {
1429     /* Quickly return if nothing to do */
1430     if (theta != 0)
1431     {
1432         /* CORDIC implementation of rotating a vector with given angle
1433         *
1434         * theta = 16bit representation of the angle in [-pi = -32768, +pi = 32767] range to rotate the PCT with
1435         * pct_i = I component of PCT
1436         * pct_q = Q component of PCT
1437         * */
1438         #define PI_div2 (1 << (16-2))
1439 
1440         /* The LUT and normalization factor is generated by the following python expression:
1441         *
1442         * f = 1.0
1443         * for i in range(NBITS):
1444         *     x = np.arctan(1 / 2**i) / (np.pi/2) * (2**NBITS)
1445         *     atanLut += [ (np.floor)(x + 0.5) ]
1446         *
1447         *     f = (f * (2**(2*i) + 1)) / 2**(2*i)
1448         *
1449         * f = 1/np.sqrt(f) * (2**NBITS)
1450         * K = (np.floor) (f + 0.5)
1451         * */
1452         #define NBITS  (14)
1453         #define K14    (9949)
1454         const uint16_t atanLut[NBITS] = { 8192, 4836, 2555, 1297, 651, 326, 163, 81, 41, 20, 10, 5, 3, 1 };
1455 
1456         /* Swap coordinates when angle is between [-pi,-pi/2] or [pi/2,pi] */
1457         int32_t x = ((int32_t) *pct_i);
1458         int32_t y = ((int32_t) *pct_q);
1459         if (theta > PI_div2)
1460         {
1461             theta -= PI_div2;
1462             x = -((int32_t) *pct_q);
1463             y = +((int32_t) *pct_i);
1464         }
1465         else if (theta < (-PI_div2))
1466         {
1467             theta += PI_div2;
1468             x = +((int32_t) *pct_q);
1469             y = -((int32_t) *pct_i);
1470         }
1471         x *= K14;
1472         y *= K14;
1473 
1474         /* Initialize local variables */
1475         int32_t x1  = 0;
1476         int32_t y1  = 0;
1477 
1478         /* The direction follows the mathematical positive direction */
1479         int32_t phi = (int32_t)(-theta);
1480 
1481         /* Rotate iteratively */
1482         for (uint8_t i = 0; i < NBITS; i++)
1483         {
1484             if (phi < 0)
1485             {   /* Counter-clockwise */
1486                 phi += atanLut[i];
1487                 y1 = y + (x >> i);
1488                 x1 = x - (y >> i);
1489             }
1490             else
1491             {   /* Clockwise */
1492                 phi -= atanLut[i];
1493                 y1 = y - (x >> i);
1494                 x1 = x + (y >> i);
1495             }
1496 
1497             x = x1;
1498             y = y1;
1499         }
1500 
1501         /* Scale according to LUT normalization weight */
1502         *pct_i = (x >> NBITS);
1503         *pct_q = (y >> NBITS);
1504     }
1505 }
1506 
1507 /*
1508  *  ======== RCL_Handler_BLE_CS_convertPct ========
1509  */
RCL_Handler_BLE_CS_convertPct(int16_t pct_i,int16_t pct_q,uint8_t channelIdx)1510 static uint32_t RCL_Handler_BLE_CS_convertPct(int16_t pct_i, int16_t pct_q, uint8_t channelIdx)
1511 {
1512     /* Calibrate via the t_picosec parameter */
1513     #define t_picosec       (uint64_t)(1000)
1514     #define t_picosec_      (uint64_t)(t_picosec * 3/2)
1515     #define t_const         (uint64_t)((t_picosec_ << 31) / 1e6)
1516     #define t_scaler        (15)
1517     #define CALC_ANGLE(ch)  (-(int16_t)((((uint64_t)ch) * t_const) >> t_scaler))
1518 
1519     /* Adjust the phase to the signal on the antenna (group delay and layout) */
1520     RCL_Handler_BLE_CS_rotateVector(&pct_i, &pct_q, CALC_ANGLE(channelIdx));
1521 
1522     /* Compress PCTs to 24bit */
1523     uint32_t pct = (((pct_q >> 1) & 0x0FFF) << 12)
1524                  | ( (pct_i >> 1) & 0x0FFF);
1525 
1526     return (pct);
1527 }
1528 
1529 /*
1530  *  ======== RCL_Handler_BLE_CS_convertPctQuality ========
1531  */
RCL_Handler_BLE_CS_convertPctQuality(uint16_t qMin,uint16_t qMax,uint16_t qAvg,bool toneExtensionSlot,bool toneExpected)1532 static uint8_t RCL_Handler_BLE_CS_convertPctQuality(uint16_t qMin, uint16_t qMax, uint16_t qAvg, bool toneExtensionSlot, bool toneExpected)
1533 {
1534     /* Initialize with unavailable */
1535     uint8_t tnQ = RCL_CmdBleCs_ToneQuality_Unavailable;
1536 
1537     /* Avoid zero-division. Metric is unavailable. Also for Initiator mode-3. */
1538     if (qAvg != 0)
1539     {
1540         /* Calculate Q3 scale */
1541         uint8_t Q3 = 100 * (qMax - qMin)/qAvg;
1542 
1543         /* Classify based on thresholds */
1544         if      (Q3 < BLE_CS_TONE_QUALITY_GOOD_THR)   tnQ = RCL_CmdBleCs_ToneQuality_Good;
1545         else if (Q3 < BLE_CS_TONE_QUALITY_MEDIUM_THR) tnQ = RCL_CmdBleCs_ToneQuality_Medium;
1546         else                                          tnQ = RCL_CmdBleCs_ToneQuality_Low;
1547 
1548         /* Add additional flag for the tone extension slot */
1549         if (toneExtensionSlot)
1550         {
1551             /* Decode the appropriate flag */
1552             uint8_t toneExtensionFlag = (toneExpected)
1553                                       ? (RCL_CmdBleCs_ToneExtensionSlot_Enabled_ToneExpected)
1554                                       : (RCL_CmdBleCs_ToneExtensionSlot_Enabled_NoToneExpected);
1555 
1556             tnQ |= (toneExtensionFlag << 4);
1557         }
1558     }
1559 
1560     return (tnQ);
1561 }
1562 
1563 /*
1564  *  ======== RCL_Handler_BLE_CS_estimateStepResultLength ========
1565  */
RCL_Handler_BLE_CS_estimateStepResultLength(RCL_CmdBleCs * pCmd,RCL_CmdBleCs_StepResult_Internal * src)1566 static uint16_t RCL_Handler_BLE_CS_estimateStepResultLength(RCL_CmdBleCs *pCmd, RCL_CmdBleCs_StepResult_Internal* src)
1567 {
1568     /* Information extracted from registers */
1569     uint8_t role           = pCmd->mode.role;
1570     uint8_t numAntennaPath = pCmd->stats->numAntennaPath + 1; // +1 = tone extension
1571 
1572     /* First two fields are mandatory */
1573     uint16_t length = 0;
1574 
1575     /* Dataformat varies based on the mode. Constants are known from the spec */
1576     switch (src->mode)
1577     {
1578         case (RCL_CmdBleCs_StepMode_0):
1579             /* Initiator also contains the measured frequency offset */
1580             length = (role == RCL_CmdBleCs_Role_Initiator) ? sizeof(RCL_CmdBleCs_ResultI0) : sizeof(RCL_CmdBleCs_ResultR0);
1581             break;
1582         case (RCL_CmdBleCs_StepMode_1):
1583             length = sizeof(RCL_CmdBleCs_ResultIR1);
1584             break;
1585         case (RCL_CmdBleCs_StepMode_2):
1586             length = sizeof(RCL_CmdBleCs_ResultIR2) + numAntennaPath * sizeof(RCL_CmdBleCs_Tone);
1587             break;
1588         case (RCL_CmdBleCs_StepMode_3):
1589             length = sizeof(RCL_CmdBleCs_ResultIR3) + numAntennaPath * sizeof(RCL_CmdBleCs_Tone);
1590             break;
1591     }
1592 
1593     return (length);
1594 }
1595 
1596 /*
1597  *  ======== RCL_Handler_BLE_CS_convertStepResult ========
1598  */
RCL_Handler_BLE_CS_convertStepResult(RCL_CmdBleCs * pCmd,uint8_t * dst,RCL_CmdBleCs_StepResult_Internal * src)1599 static uint16_t RCL_Handler_BLE_CS_convertStepResult(RCL_CmdBleCs* pCmd, uint8_t *dst, RCL_CmdBleCs_StepResult_Internal* src)
1600 {
1601     #define NADM_NOT_SUPPORTED 0xFF
1602     #define PACKET_ANTENNA     1
1603 
1604     uint8_t numAntennaPath = pCmd->stats->numAntennaPath + 1; // +1 = tone extension
1605 
1606     /* Use register access to guarantee the latest-greatest value for the first burst */
1607     int16_t foff = RCL_Handler_BLE_CS_convertFreqOffset(HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_FOFFCOMP) << 2);
1608 
1609     /* Dataformat varies based on the mode */
1610     uint8_t mode          = src->mode;
1611     uint8_t channel       = src->channelIdx;
1612     uint8_t payloadLen    = src->payloadLen;
1613     uint8_t toneExtension = src->toneExtension;
1614 
1615     /* Mode independent fields */
1616     *dst++ = mode;
1617     *dst++ = channel;
1618 
1619     /* Remember the address of field 'datalength' and skip it for now, will be filled later */
1620     uint8_t *dataLength = dst++;
1621 
1622     if (mode == RCL_CmdBleCs_StepMode_0)
1623     {
1624         *dst++ = src->pktResult;   /* Packet_AA_Quality */
1625         *dst++ = src->pktRssi;     /* Packet_RSSI */
1626         *dst++ = PACKET_ANTENNA;   /* Packet_Antenna */
1627 
1628         if (pCmd->mode.role == RCL_CmdBleCs_Role_Initiator)
1629         {
1630             int16_t freqOffset = RCL_Handler_BLE_CS_convertFreqOffset(src->foffMeasured);
1631             *dst++ = INT16_LSB(freqOffset);
1632             *dst++ = INT16_MSB(freqOffset);
1633         }
1634     }
1635     else if (mode == RCL_CmdBleCs_StepMode_1)
1636     {
1637         *dst++ = src->pktResult;     /* Packet_AA_Quality */
1638         *dst++ = NADM_NOT_SUPPORTED; /* Packet_NADM */
1639         *dst++ = src->pktRssi;       /* Packet_RSSI */
1640         *dst++ = PACKET_ANTENNA;     /* Packet_Antenna */
1641 
1642         /* RTT calculation using correlator values */
1643         int16_t toAD = RCL_Handler_BLE_CS_convertRtt(pCmd,
1644                                                      RCL_CmdBleCs_StepMode_1,
1645                                                      channel,
1646                                                      foff,
1647                                                      payloadLen,
1648                                                      false, // secondToneExtensionSlot=NA, there are no tones in mode-1
1649                                                      src->rtt, src->corr[0], src->corr[1], src->corr[2]);
1650         *dst++ = INT16_LSB(toAD);
1651         *dst++ = INT16_MSB(toAD);
1652     }
1653     else if (mode == RCL_CmdBleCs_StepMode_2)
1654     {
1655         *dst++ = src->antennaPermIdx;
1656         for (uint8_t j = 0; j < numAntennaPath; j++)
1657         {
1658             /* Compress PCT to 24bits */
1659             int16_t i = src->pct[j].i;
1660             int16_t q = src->pct[j].q;
1661 
1662             uint32_t pct = RCL_Handler_BLE_CS_convertPct(i, q, channel);
1663             *dst++       = (uint8_t)((pct) & 0xFF);
1664             *dst++       = (uint8_t)((pct >> 8) & 0xFF);
1665             *dst++       = (uint8_t)((pct >> 16) & 0xFF);
1666 
1667             /* Calculate PCT quality */
1668             bool toneExtensionSlot = (bool)(j == (numAntennaPath - 1));
1669             bool toneExpected = (bool)((pCmd->mode.role == RCL_CmdBleCs_Role_Reflector)
1670                               ? (toneExtension & BLE_CS_TONE_EXTENSION_INITIATOR_TX)
1671                               : (toneExtension & BLE_CS_TONE_EXTENSION_REFLECTOR_TX));
1672 
1673             uint16_t min = src->magn[j].magnMin;
1674             uint16_t max = src->magn[j].magnMax;
1675             uint16_t avg = src->magn[j].magnAvg;
1676             *dst++ = RCL_Handler_BLE_CS_convertPctQuality(min, max, avg, toneExtensionSlot, toneExpected);
1677         }
1678     }
1679     else if (mode == RCL_CmdBleCs_StepMode_3)
1680     {
1681         /* Packet related data */
1682         *dst++ = src->pktResult;                     /* Packet_AA_Quality */
1683         *dst++ = NADM_NOT_SUPPORTED;                 /* Packet_NADM */
1684         *dst++ = src->pktRssi;                       /* Packet_RSSI */
1685         *dst++ = PACKET_ANTENNA;                     /* Packet_Antenna */
1686 
1687         /* RTT calculation using correlator values */
1688         int16_t toAD = RCL_Handler_BLE_CS_convertRtt(pCmd,
1689                                                      RCL_CmdBleCs_StepMode_3,
1690                                                      channel,
1691                                                      foff,
1692                                                      payloadLen,
1693                                                      (bool)(toneExtension & 2),
1694                                                      src->rtt, src->corr[0], src->corr[1], src->corr[2]);
1695         *dst++ = INT16_LSB(toAD);
1696         *dst++ = INT16_MSB(toAD);
1697 
1698         /* Tone related data */
1699         *dst++ = src->antennaPermIdx;
1700         for (uint8_t j = 0; j < numAntennaPath; j++)
1701         {
1702             /* Compress PCT to 24bits */
1703             int16_t i = src->pct[j].i;
1704             int16_t q = src->pct[j].q;
1705 
1706             uint32_t pct = RCL_Handler_BLE_CS_convertPct(i, q, channel);
1707             *dst++       = (uint8_t)((pct) & 0xFF);
1708             *dst++       = (uint8_t)((pct >> 8) & 0xFF);
1709             *dst++       = (uint8_t)((pct >> 16) & 0xFF);
1710 
1711             /* Calculate PCT quality */
1712             bool toneExtensionSlot = (bool)(j == (numAntennaPath - 1));
1713 
1714             /* Mode-3 may or may not have the R->I tone extension present */
1715             bool toneExpected = (bool)((pCmd->mode.role == RCL_CmdBleCs_Role_Reflector)
1716                               ? (toneExtension & BLE_CS_TONE_EXTENSION_INITIATOR_TX)
1717                               : (toneExtension & BLE_CS_TONE_EXTENSION_REFLECTOR_TX));
1718 
1719             uint16_t min = src->magn[j].magnMin;
1720             uint16_t max = src->magn[j].magnMax;
1721             uint16_t avg = src->magn[j].magnAvg;
1722             *dst++ = RCL_Handler_BLE_CS_convertPctQuality(min, max, avg, toneExtensionSlot, toneExpected);
1723         }
1724     }
1725 
1726     /* Fill the Step_Data_Length based on difference of addresses */
1727     *dataLength = (dst - dataLength - 1);
1728 
1729     /* Return the number of bytes written (+3 = mode&channel&dataLength) */
1730     return (*dataLength + 3);
1731 }
1732 
1733 /*
1734  *  ======== RCL_Handler_BLE_CS_findPbeErrorEndStatus ========
1735  */
RCL_Handler_BLE_CS_findPbeErrorEndStatus(uint16_t pbeEndStatus)1736 static RCL_CommandStatus RCL_Handler_BLE_CS_findPbeErrorEndStatus(uint16_t pbeEndStatus)
1737 {
1738     RCL_CommandStatus status;
1739     switch (pbeEndStatus)
1740     {
1741     case PBE_COMMON_RAM_ENDCAUSE_STAT_ERR_RXF:
1742         status = RCL_CommandStatus_Error_RxFifo;
1743         break;
1744     case PBE_COMMON_RAM_ENDCAUSE_STAT_ERR_TXF:
1745         status = RCL_CommandStatus_Error_TxFifo;
1746         break;
1747     case PBE_COMMON_RAM_ENDCAUSE_STAT_ERR_SYNTH:
1748         status = RCL_CommandStatus_Error_Synth;
1749         break;
1750     case PBE_COMMON_RAM_ENDCAUSE_STAT_ERR_STOP:
1751         status = RCL_Scheduler_findStopStatus(RCL_StopType_Hard);
1752         break;
1753     case PBE_COMMON_RAM_ENDCAUSE_STAT_ERR_PAR:
1754         status = RCL_CommandStatus_Error_Param;
1755         break;
1756     case PBE_COMMON_RAM_ENDCAUSE_STAT_ERR_BADOP:
1757         status = RCL_CommandStatus_Error_UnknownOp;
1758         break;
1759     default:
1760         Log_printf(RclCore, Log_ERROR, "Unexpected error 0x%04X from PBE", pbeEndStatus);
1761         status = RCL_CommandStatus_Error;
1762         break;
1763     }
1764     return (status);
1765 }
1766 
1767 /*
1768  *  ======== RCL_Handler_BLE_CS ========
1769  */
RCL_Handler_BLE_CS(RCL_Command * cmd,LRF_Events lrfEvents,RCL_Events rclEventsIn)1770 RCL_Events RCL_Handler_BLE_CS(RCL_Command *cmd, LRF_Events lrfEvents, RCL_Events rclEventsIn)
1771 {
1772     RCL_CmdBleCs *pCmd = (RCL_CmdBleCs *) cmd;
1773     RCL_Events rclEvents = {.value = 0};
1774 
1775     if (rclEventsIn.setup != 0)
1776     {
1777         uint32_t earliestStartTime;
1778 
1779         /* Start by enabling refsys */
1780         earliestStartTime = LRF_enableSynthRefsys();
1781 
1782         /* Check if valid PLLDIV0 synth setting is used. */
1783         /* BLE CS currently supports only either 3 => FREF0=16MHz or 12 => FREF0=4MHz */
1784         uint32_t plldiv0 = (HWREG_READ_LRF(LRFDRFE_BASE + LRFDRFE_O_PRE0) & LRFDRFE_PRE0_PLLDIV0_M) >> LRFDRFE_PRE0_PLLDIV0_S;
1785         if ((plldiv0 != 3U) && (plldiv0 != 12U))
1786         {
1787             /* Override to use PLLDIV0=12, gives FREF0=4MHz */
1788             Log_printf(RclCore, Log_WARNING, "Unsupported RFE_PRE0_PLLDIV0 synth setting detected. Will override to use 12 (FREF=4MHz)");
1789             HWREG_WRITE_LRF(LRFDRFE_BASE + LRFDRFE_O_PRE0) = ((12U << LRFDRFE_PRE0_PLLDIV0_S) & LRFDRFE_PRE0_PLLDIV0_M) |
1790                                                              ((12U << LRFDRFE_PRE0_PLLDIV1_S) & LRFDRFE_PRE0_PLLDIV1_M);
1791         }
1792 
1793         /* Mark as active */
1794         cmd->status = RCL_CommandStatus_Active;
1795 
1796         /* Default end status */
1797         bleCsHandlerState.common.endStatus = RCL_CommandStatus_Finished;
1798 
1799         /* Enable radio */
1800         LRF_enable();
1801 
1802         RCL_CommandStatus startTimeStatus = RCL_Scheduler_setStartStopTimeEarliestStart(cmd, earliestStartTime);
1803         if (startTimeStatus >= RCL_CommandStatus_Finished)
1804         {
1805             cmd->status = startTimeStatus;
1806             rclEvents.lastCmdDone = 1;
1807         }
1808         else
1809         {
1810             /* Enable interrupts (LRF_EventMdmsoft0 => "S2R samples available") */
1811             HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) =
1812                             HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0)
1813                             | LRF_EventOpDone.value
1814                             | LRF_EventOpError.value
1815                             | LRF_EventMdmsoft0.value
1816                             | LRF_EventRxfifo.value;
1817 
1818             /* Initialize BLE CS specific registers and FIFO */
1819             RCL_Handler_BLE_CS_preprocessCommand(pCmd);
1820 
1821             /* Configure TX power*/
1822             if (LRF_programTxPower(pCmd->frontend.txPower) != TxPowerResult_Ok)
1823             {
1824                 cmd->status = RCL_CommandStatus_Error_Param;
1825                 rclEvents.lastCmdDone = 1;
1826             }
1827             else
1828             {
1829                 /* Configure the BUFRAM fifo size and interrupts */
1830                 RCL_Handler_BLE_CS_configureTxRxFifo(pCmd);
1831 
1832                 /* Configure S2R size and mode */
1833                 RCL_Handler_BLE_CS_configureS2R(pCmd);
1834 
1835                 /* Fill the first batch of step descriptors into the BUFRAM TX fifo */
1836                 RCL_Handler_BLE_CS_preFillTxBuffer(pCmd);
1837 
1838                 /* Post command */
1839                 LRF_waitForTopsmReady();
1840                 HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_COMMON_RAM_O_MSGBOX) = 0;
1841                 HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_API) = PBE_BLE_CS_REGDEF_API_OP_BLE_CS;
1842 
1843                 /* Forward fill more steps */
1844                 RCL_Handler_BLE_CS_preFillTxBuffer(pCmd);
1845             }
1846         }
1847     }
1848 
1849     if (cmd->status == RCL_CommandStatus_Active)
1850     {
1851         /* Read the statistics */
1852         RCL_Handler_BLE_CS_readStatistics(pCmd);
1853 
1854         if (rclEventsIn.timerStart != 0)
1855         {
1856             rclEvents.cmdStarted = 1;
1857         }
1858 
1859         if (lrfEvents.opDone != 0 || lrfEvents.opError != 0)
1860         {
1861             /* Drain the rx fifo of the final batch of results. Force close the buffer. */
1862             rclEvents.value |= RCL_Handler_BLE_CS_readWriteBuffer(pCmd, true).value;
1863         }
1864         else
1865         {
1866             if (lrfEvents.rxfifo != 0)
1867             {
1868                 /* Read the available results, and issue event if multibuffer is exhausted */
1869                 rclEvents.value |= RCL_Handler_BLE_CS_readWriteBuffer(pCmd, false).value;
1870             }
1871         }
1872 
1873         if (lrfEvents.mdmsoft0 != 0)
1874         {
1875             /* Read S2R samples upon MCE event */
1876             rclEvents.value |= RCL_Handler_BLE_CS_readS2RSamples(pCmd).value;
1877         }
1878 
1879         if (lrfEvents.opDone != 0)
1880         {
1881             cmd->status = bleCsHandlerState.common.endStatus;
1882             rclEvents.lastCmdDone = 1;
1883         }
1884         else if (lrfEvents.opError != 0)
1885         {
1886             RCL_CommandStatus endStatus = bleCsHandlerState.common.endStatus;
1887             if (endStatus == RCL_CommandStatus_Finished)
1888             {
1889                 cmd->status = RCL_Handler_BLE_CS_findPbeErrorEndStatus(HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_COMMON_RAM_O_ENDCAUSE));
1890             }
1891             else
1892             {
1893                 cmd->status = endStatus;
1894             }
1895             rclEvents.lastCmdDone = 1;
1896         }
1897         else
1898         {
1899             /* Other events need to be handled unconditionally */
1900         }
1901     }
1902 
1903     if (rclEvents.lastCmdDone != 0)
1904     {
1905         LRF_disable();
1906         LRF_disableSynthRefsys();
1907     }
1908     return (rclEvents);
1909 }
1910 
1911 
1912 
1913 /*
1914  *  ======== RCL_Handler_BLE_CS_Precal ========
1915  */
RCL_Handler_BLE_CS_Precal(RCL_Command * cmd,LRF_Events lrfEvents,RCL_Events rclEventsIn)1916 RCL_Events RCL_Handler_BLE_CS_Precal(RCL_Command *cmd, LRF_Events lrfEvents, RCL_Events rclEventsIn)
1917 {
1918     RCL_CmdBleCs_Precal *pCmd = (RCL_CmdBleCs_Precal *) cmd;
1919     RCL_Events rclEvents = {.value = 0};
1920 
1921     if (rclEventsIn.setup != 0)
1922     {
1923         uint32_t earliestStartTime;
1924 
1925         /* Start by enabling refsys */
1926         earliestStartTime = LRF_enableSynthRefsys();
1927 
1928         /* Mark as active */
1929         cmd->status = RCL_CommandStatus_Active;
1930 
1931         /* Default end status */
1932         bleCsHandlerState.common.endStatus = RCL_CommandStatus_Finished;
1933 
1934         /* Enable radio */
1935         LRF_enable();
1936 
1937         RCL_CommandStatus startTimeStatus = RCL_Scheduler_setStartStopTimeEarliestStart(cmd, earliestStartTime);
1938         if (startTimeStatus >= RCL_CommandStatus_Finished)
1939         {
1940             cmd->status = startTimeStatus;
1941             rclEvents.lastCmdDone = 1;
1942         }
1943         else
1944         {
1945             /* Enable interrupts */
1946             HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0)
1947                             = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0)
1948                             | LRF_EventOpDone.value
1949                             | LRF_EventOpError.value;
1950 
1951             RCL_Handler_BLE_CS_configureTxRxFifo(NULL);
1952 
1953             /* Number of channels to calibrate on */
1954             HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_BLE_CS_RAM_O_MODE) = ((pCmd->table->numEntries << PBE_BLE_CS_RAM_MODE_NUM_STEPS_S) & PBE_BLE_CS_RAM_MODE_NUM_STEPS_M);
1955             HWREG_WRITE_LRF(LRFDRFE_BASE + LRFDRFE_O_SPARE0) = pCmd->table->rxGain;
1956 
1957             for (uint8_t j=0; j<pCmd->table->numEntries; j++)
1958             {
1959                 /* 32bit aperture */
1960                 HWREG_WRITE_LRF(LRFDTXF_BASE + LRFDTXF_O_TXD) = pCmd->table->entries[j].channel;
1961             }
1962 
1963             /* Post command */
1964             LRF_waitForTopsmReady();
1965             HWREGH_WRITE_LRF(LRFD_BUFRAM_BASE + PBE_COMMON_RAM_O_MSGBOX) = 0;
1966             HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_API) = PBE_BLE_CS_REGDEF_API_OP_PRECAL;
1967         }
1968     }
1969 
1970     if (cmd->status == RCL_CommandStatus_Active)
1971     {
1972         if (lrfEvents.opDone != 0)
1973         {
1974             for (uint8_t j=0; j<pCmd->table->numEntries; j++)
1975             {
1976                 /* uint32_t per read via the FIFO */
1977                 uint32_t data = HWREG_READ_LRF(LRFDRXF_BASE + LRFDRXF_O_RXD);
1978                 pCmd->table->entries[j].hdc.i = ((data >> 0 ) & 0xFFFF);
1979                 pCmd->table->entries[j].hdc.q = ((data >> 16) & 0xFFFF);
1980 
1981                 data = HWREG_READ_LRF(LRFDRXF_BASE + LRFDRXF_O_RXD);
1982                 pCmd->table->entries[j].ldc.i = ((data >> 0 ) & 0xFFFF);
1983                 pCmd->table->entries[j].ldc.q = ((data >> 16) & 0xFFFF);
1984             }
1985 
1986             /* Validate the table */
1987             pCmd->table->valid = 1;
1988 
1989             cmd->status = bleCsHandlerState.common.endStatus;
1990             rclEvents.lastCmdDone = 1;
1991         }
1992         else if (lrfEvents.opError != 0)
1993         {
1994             /* Invalidate the table */
1995             pCmd->table->valid = 0;
1996 
1997             RCL_CommandStatus endStatus = bleCsHandlerState.common.endStatus;
1998             if (endStatus == RCL_CommandStatus_Finished)
1999             {
2000                 cmd->status = RCL_Handler_BLE_CS_findPbeErrorEndStatus(HWREGH_READ_LRF(LRFD_BUFRAM_BASE + PBE_COMMON_RAM_O_ENDCAUSE));
2001             }
2002             else
2003             {
2004                 cmd->status = endStatus;
2005             }
2006             rclEvents.lastCmdDone = 1;
2007         }
2008         else
2009         {
2010            /* Other events need to be handled unconditionally */
2011         }
2012     }
2013 
2014     if (rclEvents.lastCmdDone != 0)
2015     {
2016         LRF_disable();
2017         LRF_disableSynthRefsys();
2018     }
2019     return (rclEvents);
2020 }
2021 
2022 /*
2023  *  ======== RCL_Handler_BLE_CS_PrecalDefaultCallback ========
2024  */
RCL_Handler_BLE_CS_PrecalDefaultCallback(RCL_CmdBleCs_PrecalTable * table,uint8_t channel,uint32_t * hdc,uint32_t * ldc)2025 void RCL_Handler_BLE_CS_PrecalDefaultCallback(RCL_CmdBleCs_PrecalTable *table, uint8_t channel, uint32_t *hdc, uint32_t *ldc)
2026 {
2027     *hdc = 0;
2028     *ldc = 0;
2029 
2030     if (channel <= BLE_CS_MAX_CHANNEL)
2031     {
2032         /* Default channel blocks : 10-30-50-70 MHz */
2033         #define BLE_CS_PRECAL_BIN_WIDTH 20
2034 
2035         uint8_t k = channel / BLE_CS_PRECAL_BIN_WIDTH;
2036 
2037         if (k < table->numEntries)
2038         {
2039             /* Populate the DC measured with high gain */
2040             uint32_t i = table->entries[k].hdc.i;
2041             uint32_t q = table->entries[k].hdc.q;
2042             *hdc = (q << 16 | i);
2043 
2044             i = table->entries[k].ldc.i;
2045             q = table->entries[k].ldc.q;
2046             *ldc = (q << 16 | i);
2047         }
2048     }
2049 }
2050