1 /*
2  * Copyright 2018 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef BS_P2G4_TYPES_H
7 #define BS_P2G4_TYPES_H
8 
9 #include "bs_types.h"
10 #include "bs_pc_base_types.h"
11 #include "bs_pc_2G4_modulations.h"
12 
13 #ifdef __cplusplus
14 extern "C"{
15 #endif
16 
17 /*
18  * From 0.0 to 80.0 in which frequency is the transmission centered
19  * format 8.8 in MHz, offset relative to 2400
20  * (can be negative for blockers < 2400)
21  */
22 typedef int16_t  p2G4_freq_t;
23 #define P2G4_freq_FRACB 8
24 #define P2G4_INVALID_FREQ 0x7FFF
25 
26 /* Power level in dBm or gain in dB (depending on context).
27  * Format 8.8 (-128.0 .. 127.99609375)*/
28 typedef int16_t  p2G4_power_t;
29 #define P2G4_POWER_MIN INT16_MIN
30 /* RSSI measured power level in dBm, format signed 16.16
31  * from -32768.0 .. 32768-1/2^16 dBm with a resolution of 1/2^16 = 1.5e-5dBm */
32 typedef int32_t  p2G4_rssi_power_t;
33 #define P2G4_RSSI_POWER_MIN INT32_MIN
34 
35 typedef uint16_t p2G4_modulation_t;
36 
37 #define P2G4_RXV2_MAX_ADDRESSES 16
38 typedef uint64_t p2G4_address_t;
39 
40 typedef struct __attribute__ ((packed)) {
41   /* At this point the Tx/Rx will be stopped abruptly
42    * If not used, set to TIME_NEVER */
43   bs_time_t abort_time;
44   /* Time in which the phy should check if the device wants
45    * to change its mind regarding the next abort time.
46    * If not used set to TIME_NEVER */
47   bs_time_t recheck_time;
48 } p2G4_abort_t;
49 
50 typedef struct __attribute__ ((packed)) {
51   /* One of P2G4_MOD_* */
52   p2G4_modulation_t modulation;
53   /* Carrier frequency */
54   p2G4_freq_t  center_freq;
55 } p2G4_radioparams_t;
56 
57 typedef struct __attribute__ ((packed)) {
58   /* Absolute microsecond when the measurement should be taken */
59   bs_time_t meas_time;
60   p2G4_radioparams_t radio_params;
61   p2G4_power_t antenna_gain;
62 } p2G4_rssi_t ;
63 
64 typedef struct __attribute__ ((packed)) {
65   /* RSSI measured value by the modem */
66   p2G4_rssi_power_t RSSI;
67 } p2G4_rssi_done_t;
68 
69 typedef struct __attribute__ ((packed)) {
70   /* Absolute us when the receiver starts scanning */
71   bs_time_t start_time;
72   /* Time in which we need to get a preamble + address match before giving up
73    * Once we get a preamble + address match we will continue to receive the
74    * whole packet, unless there is a header error.
75    * We scan in the range [ start_time,  start_time + scan_duration - 1] us */
76   uint32_t scan_duration;
77   /* Address we search for */
78   uint32_t phy_address;
79   p2G4_radioparams_t radio_params;
80   p2G4_power_t antenna_gain;
81   /* Reception tolerance: */
82   /* How many errors do we accept before considering the preamble + address sync lost
83    * (if there is less errors than this the packet can be received correctly) */
84   uint16_t sync_threshold;
85   /* How many errors do we accept in the header before giving a header error
86    * (automatically in the phy)
87    * Note: any header error will result at least in a CRC error
88    */
89   uint16_t header_threshold;
90   /* Packet parameters: */
91   /*in us, duration of the preamble and start flag */
92   uint16_t pream_and_addr_duration;
93   /* in us duration of the BLE header */
94   uint16_t header_duration;
95   /*
96    * Data rate in bits per second
97    */
98   uint32_t bps;
99   /*
100    * Structure defining when the device may want to abort the reception
101    * Note: abort_time shall be > start_time
102    */
103   p2G4_abort_t abort;
104 } p2G4_rx_t;
105 
106 typedef struct __attribute__ ((packed)) {
107   /* absolute us when the first bit of the packet is sent to the air
108    * = the begining of the preamble */
109   bs_time_t start_time;
110   /* absolute us when the last bit of the packet is sent to the air */
111   bs_time_t end_time;
112   /*
113    * Structure defining when the device may want to abort the transmission
114    * Note: abort_time shall be > start_time
115    */
116   p2G4_abort_t abort;
117   /* Phy address/access code used in the packet */
118   uint32_t phy_address;
119   p2G4_radioparams_t radio_params;
120   /* In dBm, transmitter power level (including antenna gain) */
121   p2G4_power_t power_level;
122   /* Packet size in bytes; Only used for moving the payload, not modeling related */
123   uint16_t packet_size;
124 } p2G4_tx_t;
125 
126 typedef struct __attribute__ ((packed)) {
127   /* one of P2G4_RXSTATUS* */
128   uint16_t status;
129   /* Found packet size in bytes */
130   uint16_t packet_size;
131   /* if Status != P2G4_RXSTATUS_NOSYNC: absolute us when the address ended.
132    * otherwise when the scan window ended */
133   bs_time_t rx_time_stamp;
134   /* Absolute us this message is sent */
135   bs_time_t end_time;
136   /* RSSI measured values by the modem */
137   p2G4_rssi_done_t rssi;
138 } p2G4_rx_done_t;
139 
140 #define P2G4_RXSTATUS_OK            0x1
141 #define P2G4_RXSTATUS_CRC_ERROR     0x2 /* At least 1 bit error was detected during the header or payload */
142 #define P2G4_RXSTATUS_PACKET_CONTENT_ERROR 0x2 /* Rename of CRC_ERROR */
143 #define P2G4_RXSTATUS_HEADER_ERROR  0x3 /* More bit errors found during header than <header_threshold> */
144 #define P2G4_RXSTATUS_NOSYNC        0x4 /*Nothing was synchronized*/
145 #define P2G4_RXSTATUS_INPROGRESS    0x5 /*The reception is/was ongoing*/
146 
147 typedef struct __attribute__ ((packed)) {
148   /* absolute us this message is sent */
149   bs_time_t end_time;
150 } p2G4_tx_done_t;
151 
152 
153 /************************************************************
154  * V2 API extension
155  * In *Alpha* state, API backward/forward compatibility NOT guaranteed.
156  * API breaking changes can be expected in future releases
157  *
158  * This includes:
159  *  * Txv2 procedure p2G4_txv2_t (followed by p2G4_tx_done_t)
160  *  * Rxv2 procedure p2G4_rxv2_t & p2G4_rxv2_done_t
161  *  * CCA search procedure p2G4_search_comp_mod_done_t & p2G4_search_comp_mod_t
162  *
163  * Note this API includes the Txv2 and Rxv2 procedures which provide
164  * a superset of the functionality their v1 counterparts supported
165  * The v1 and v2 procedures are fully cross-compatible
166  * (within the limitation imposed by the v1 party)
167  *
168  * The v1 API is NOT deprecated:
169  * Devices utilizing the v1 API are not expected to migrate to the
170  * new API, and are discouraged from doing so while the
171  * API is in alpha and beta state.
172  ************************************************************/
173 
174 typedef struct __attribute__ ((packed)) {
175   /* Absolute us when the transmittion starts.
176    * This will typically be the same as start_packet_time.
177    * But, it may be:
178    *  * Earlier, if the transmitter starts emitting a spurious carrier
179    *    or similar before the actual packet start
180    *  * The transmitter eats into the preamble by ramping up too late
181    *
182    * Note: The device must send this request no later than the Phy simulated time start_tx_time
183    */
184   bs_time_t start_tx_time;
185   /* Absolute us when the transmitter stops transmitting
186    * This will typically be the same as end_packet_time.
187    * But, it may be:
188    *  * Longer, if the transmitter continuous emitting a spurious carrier
189    *    or desired (i.e. BLE CTE) after the actual packet end
190    */
191   bs_time_t end_tx_time;
192 
193   /* Absolute us when the first bit of a protocol compliant packet would be sent to the air
194    * i.e. typically the beginning of the preamble
195    * Note that a real transmitter may send some carrier/noise before this,
196    * or may be purposely configured to truncate the beginning of the preamble.
197    * Neither of these 2 effects should be reflected in this value
198    */
199   bs_time_t start_packet_time;
200   /* Absolute us when the last bit of the packet is sent to the air
201    * Note that this should only include "data" bits, and not extra transmitted tones
202    * either desired (for ex. BLE CTE) or undesired (possible spurious tails/carrier)
203    */
204   bs_time_t end_packet_time;
205 
206   /* {Phy,access} {address,code}/{sync,start} {word,flag,delimiter} used in the packet
207    * If the protocol does not use it, or uses less than 64 bits
208    * you must set the unused bits to 0
209    * For BLE this should be set to the 32bit "access address" (not encoded in case of coded phy)
210    * For 802.15.4 this should be set to the 8 bit SFD
211    * For other protocols, the address may include more than just this,
212    * while both Tx and Rx agree by convention on what it includes.
213    */
214   p2G4_address_t phy_address;
215 
216   /*
217    * Structure defining when the device may want to abort the transmission
218    * Note: abort_time shall be > start_tx_time
219    */
220   p2G4_abort_t abort;
221 
222   p2G4_radioparams_t radio_params;
223   /* In dBm, transmitter power level (including antenna gain) */
224   p2G4_power_t power_level;
225 
226   /* (if coded) Which coding rate, the data is sent with
227    * Note that this is only used for a == or != check.*/
228   uint16_t coding_rate;
229 
230   /* Packet size in bytes; Only used for moving the payload, not modeling related */
231   uint16_t packet_size;
232 
233   /* Note: For mapping the old p2G4_tx_t API to this,
234    * start_tx_time = start_packet_time = v1 start_time
235    * end_tx_time = end_packet_time = v1 end_time
236    * phy_address is just 0 extended
237    * coding_rate = 0
238    */
239 } p2G4_txv2_t;
240 
241 
242 typedef struct __attribute__ ((packed)) {
243   /* Absolute us when the receiver starts scanning */
244   bs_time_t start_time;
245 
246   /*
247    * Structure defining when the device may want to abort the reception
248    * Note: abort_time shall be > start_time
249    */
250   p2G4_abort_t abort;
251 
252   /* Time in which we need to get a preamble + address match before giving up
253    * Once we get a preamble + address match we will continue to receive the
254    * whole packet, unless there is a header error.
255    * We scan in the range [ start_time,  start_time + scan_duration - 1] us, unless
256    * scan_duration == UINT32_MAX, in which case the scan does not end (until aborted) */
257   uint32_t scan_duration;
258 
259   /* Duration of the packet the receiver will listen for.
260    * That is, for how long the receiver will be receiving bits,
261    * instead of during Tx.start_packet_time -> Tx.end_packet_time
262    * The receiver will think the packet lasts Tx.start_packet_time -> (Tx.start_packet_time+forced_packet_duration-1)
263    * A value of UINT32_MAX or 0 means it follows the Tx packet duration.
264    * Note: This is not a filter, but a way to model receivers mistakenly
265    * decoding the length or code/rate indication fields.
266    */
267   uint32_t forced_packet_duration;
268 
269   /* Error calculation rate, in times per second.
270    * Typically the data rate in bits per second (For binary FSK, PSK, ASK.. modulations)
271    * Note: This is just the bit error and SNR calculation rate.
272    * It does not affect the actual packet duration in any way.
273    * It is up to the receiver to set it in accordance with the type of modulation.
274    * For more complex modulations or coded packets, it may be the chip-rate,
275    * symbol-rate or coded-bit-rate */
276   uint32_t error_calc_rate;
277 
278   p2G4_radioparams_t radio_params;
279 
280   p2G4_power_t antenna_gain;
281 
282   /* (if coded) Which coding rate, the data is received with
283    * Note that this is only used for a == or != check. And that when set
284    * different than for the transmitter, the BER will be 50%
285    * For BLE CodedPhy, this should be set to 2 or 8 for S=2 and S=8 respectively
286    */
287   uint16_t coding_rate;
288 
289   /* Packet parameters: */
290 
291   /* In us, duration of the preamble and start flag
292    * It can be set to zero */
293   uint16_t pream_and_addr_duration;
294 
295   /* In us duration of the "header". It can be 0.
296    * For uncoded BLE this correspond to the BLE header
297    * For 15.4 this should be set to 0
298    * For Nordic's ESB this should be set to the duration of 8 bits */
299   uint16_t header_duration;
300 
301   /* Reception tolerance: */
302 
303   /* How many us into the transmitted preamble we accept having opened the receiver in,
304    * and consider it is still possible to receive a packet
305    *
306    * Note: The missing piece of the preamble will NOT be counted as having "bit errors"
307    * for the sync_threshold calculation. Actually the receive procedure will just skip
308    * the whole acceptable_pre_truncation, and start checking for bit errors after.
309    * Note: acceptable_pre_truncation must be <= pream_and_addr_duration
310    */
311   uint16_t acceptable_pre_truncation;
312 
313   /* How many errors do we accept before considering the preamble + address sync lost */
314   uint16_t sync_threshold;
315 
316   /* How many errors do we accept in the header before giving a header error
317    * (automatically in the phy)
318    * Note: any header error will result at least in a CRC/packet error
319    */
320   uint16_t header_threshold;
321 
322   /* When set to 0 the Rx is not pre-locked.
323    * When set to 1, the Rx is already pre-locked.
324    * In that case, the Rx will not search for a transmitter but continue receiving from the last
325    * transmitter that it just was.
326    * The receiver will go directly to sync mode.
327    *
328    * Note that in this case :
329    *   * scan_duration should be set to pream_and_addr_duration + 1.
330    *   * acceptable_pre_truncation should be set to 0
331    *   * it may fail during sync depending on the sync_threshold and/or the transmitter disappearing.
332    *     even if pream_and_addr_duration == 0 (an instantaneous check will be performed still).
333    *     You can avoid this from happening for bit errors by setting sync_threshold high enough (for ex. UINT16_MAX)
334    *   * Similarly it may fail during the header reception just like with a normal packet.
335    *   * Any given phy_addr[] will be ignored.
336    *
337    * Note: prelocked_tx when the previous reception failed to sync leads to undefined behaviour
338    */
339   uint8_t prelocked_tx;
340 
341   /* Requested type of response
342    *  * 0: Basic response
343    *  * (reserved) 1: Include also bit error mask
344    *  * (reserved) all others
345    */
346   uint8_t resp_type;
347 
348   /* How many addresses we actively search for, must be >= 1 & < 8
349    * And how many elements of p2G4_address_t phy_addr[] follow */
350   uint8_t n_addr;
351 
352   /* Note: For mapping the old p2G4_rx_t API to this,
353    * n_addr = 1
354    * phy_address[0] = phy_address (0 extended)
355    * error_calc_rate = v1 bps
356    * acceptable_pre_truncation = 0
357    * resp_type = 0;
358    * forced_packet_duration = UINT32_MAX
359    * coding_rate = 0
360    */
361 } p2G4_rxv2_t;
362 
363 
364 typedef struct __attribute__ ((packed)) {
365   /* if Status != P2G4_RXSTATUS_NOSYNC: absolute us when the address ended.
366    * otherwise when the scan window ended */
367   bs_time_t rx_time_stamp;
368   /* Absolute us this message is sent */
369   bs_time_t end_time;
370 
371   /*Matched address (if any)*/
372   p2G4_address_t phy_address;
373 
374   /*The transmitter coding rate*/
375   uint16_t coding_rate;
376 
377   /* RSSI measured value by the modem */
378   p2G4_rssi_done_t rssi;
379 
380   /* one of P2G4_RXSTATUS* */
381   uint16_t status;
382   /* Found packet size in bytes */
383   uint16_t packet_size;
384 
385 } p2G4_rxv2_done_t;
386 
387 
388 /**
389  * Search for a compatible modulation and/or
390  * do an average energy measurements on the channel
391  * Typically used for CCA procedures
392  */
393 typedef struct __attribute__ ((packed)) {
394   /* Absolute us when the receiver starts */
395   bs_time_t start_time;
396 
397   /*
398    * Structure defining when the device may want to abort the reception
399    * Note: abort_time shall be > start_time
400    */
401   p2G4_abort_t abort;
402 
403   /* For how long the device will check for
404    * We scan in the range [ start_time,  start_time + scan_duration - 1] us */
405   uint32_t scan_duration;
406 
407   /* Scan period
408    * How often the device wants to check
409    * The Phy will do ceil(scan_duration/scan_period) measurements, at start_time + i*scan_period */
410   uint32_t scan_period;
411 
412   /*Modulation we search for (and in which the receiver is set) and center frequency */
413   p2G4_radioparams_t radio_params;
414 
415   /* Rx power threshold with which a compatible transmitter will be considered found */
416   p2G4_rssi_power_t mod_threshold;
417   /* RSSI power threshold with which the energy detection will be considered over threshold */
418   p2G4_rssi_power_t rssi_threshold;
419 
420   /*Gain of the Rx antenna*/
421   p2G4_power_t antenna_gain;
422 
423   /* Stop as soon as a compatible modulation is found with power over mod_threshold (1)
424    * Stop as soon as any RRSI measurement is over rssi_threshold (2)
425    * either (3)
426    * Or continue until the end of the scan_duration (0) */
427   uint8_t stop_when_found;
428 } p2G4_cca_t;
429 
430 
431 typedef struct __attribute__ ((packed)) {
432   /* Absolute us this message is sent */
433   bs_time_t end_time;
434 
435   /* The averaged RSSI measurement (Of all scan_periods) */
436   p2G4_rssi_power_t RSSI_ave;
437   /* The max RSSI measurement (Of all scan_periods) */
438   p2G4_rssi_power_t RSSI_max;
439   /* RRSI power level measured when a matching Tx modulation was found (if several are found over time, the greater level) */
440   p2G4_rssi_power_t mod_rx_power;
441   /* Was a compatible transmitter with power over mod_threshold found (1) or not (0) */
442   uint8_t mod_found;
443   /* Was at any point the RRSI level over rssi_threshold (1) or not (0) */
444   uint8_t rssi_overthreshold;
445 } p2G4_cca_done_t;
446 
447 
448 /*
449  * Commands and responses IDs:
450  */
451 
452 /** Message headers from device to phy **/
453 /* The device will transmit */
454 #define P2G4_MSG_TX             0x02
455 /* The device wants to attempt to receive */
456 #define P2G4_MSG_RX             0x11
457 /* Continue receiving (the device likes the address and headers of the packet) */
458 #define P2G4_MSG_RXCONT         0x12
459 /* Stop reception (the device does not likes the address or headers of the packet) => The phy will stop this reception */
460 #define P2G4_MSG_RXSTOP         0x13
461 /* Do an RSSI measurement*/
462 #define P2G4_MSG_RSSIMEAS       0x14
463 /* Device is successfully providing a new p2G4_abort_t */
464 #define P2G4_MSG_RERESP_ABORTREEVAL 0x15
465 /* Continue receiving (the device likes the address and headers of the packet, and it provides an updated abort substructure) */
466 #define P2G4_MSG_RXV2CONT       0x16
467 
468 
469 /* The device will transmit (updated/v2 Tx API) */
470 #define P2G4_MSG_TXV2           0x22
471 /* The device wants to attempt to receive (updated/v2 Rx API) */
472 #define P2G4_MSG_RXV2           0x31
473 /* The device wants to do a CCA check (new v2 API) */
474 #define P2G4_MSG_CCA_MEAS       0x32
475 /* Device is requesting an immediate RSSI measurement during an Rx abort reevaluation (new for v2 API) */
476 #define P2G4_MSG_RERESP_IMMRSSI 0x16
477 
478 
479 /** From Phy to device **/
480 /* Tx completed (fully or not) */
481 #define P2G4_MSG_TX_END          0x100
482 /* Poking the device to see if it wants to change its abort time */
483 #define P2G4_MSG_ABORTREEVAL     0x101
484 /* Phy responds to the device with the immediate RRSI measurement
485  * while re-requesting a new abort reeval.(new for v2 API) */
486 #define P2G4_MSG_IMMRSSI_RRSI_DONE 0x102
487 
488 
489 /* Matching address found while receiving */
490 #define P2G4_MSG_RX_ADDRESSFOUND 0x102
491 /* Rx completed (successfully or not) */
492 #define P2G4_MSG_RX_END          0x103
493 /* RSSI measurement completed */
494 #define P2G4_MSG_RSSI_END        0x104
495 
496 /* Matching address found while receiving (new v2 API) */
497 #define P2G4_MSG_RXV2_ADDRESSFOUND 0x112
498 /* Rx completed (successfully or not) (new v2 API) */
499 #define P2G4_MSG_RXV2_END          0x113
500 /* Search CCA check completed (new v2 API) */
501 #define P2G4_MSG_CCA_END           0x114
502 
503 #ifdef __cplusplus
504 }
505 #endif
506 
507 #endif
508