@@ -85,6 +85,8 @@ Maintainer: Sylvain Miermont
8585#define LGW_RF_RX_BANDWIDTH_250KHZ 1000000 /* for 250KHz channels */
8686#define LGW_RF_RX_BANDWIDTH_500KHZ 1100000 /* for 500KHz channels */
8787
88+ #define TX_START_DELAY_DEFAULT 1497 /* Calibrated value for 500KHz BW and notch filter disabled */
89+
8890/* constant arrays defining hardware capability */
8991const uint8_t ifmod_config [LGW_IF_CHAIN_NB ] = LGW_IFMODEM_CONFIG ;
9092
@@ -157,12 +159,6 @@ static int8_t cal_offset_a_q[8]; /* TX Q offset for radio A */
157159static int8_t cal_offset_b_i [8 ]; /* TX I offset for radio B */
158160static int8_t cal_offset_b_q [8 ]; /* TX Q offset for radio B */
159161
160- /* -------------------------------------------------------------------------- */
161- /* --- INTERNAL SHARED VARIABLES -------------------------------------------- */
162-
163- /* TX start delay adjusted for the concentrator board used */
164- uint16_t lgw_i_tx_start_delay_us = 1500 ; /* shared with LBT module */
165-
166162/* -------------------------------------------------------------------------- */
167163/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
168164
@@ -332,7 +328,7 @@ void lgw_constant_adjust(void) {
332328 lgw_reg_w (LGW_FSK_PATTERN_TIMEOUT_CFG ,128 ); /* sync timeout (allow 8 bytes preamble + 8 bytes sync word, default 0 */
333329
334330 /* TX general parameters */
335- lgw_reg_w (LGW_TX_START_DELAY , ( int32_t ) lgw_i_tx_start_delay_us ); /* default 0 */
331+ lgw_reg_w (LGW_TX_START_DELAY , TX_START_DELAY_DEFAULT ); /* default 0 */
336332
337333 /* TX LoRa */
338334 // lgw_reg_w(LGW_TX_MODE,0); /* default 0 */
@@ -383,6 +379,36 @@ int32_t lgw_sf_getval(int x) {
383379 }
384380}
385381
382+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
383+
384+ uint16_t lgw_get_tx_start_delay (bool tx_notch_enable , uint8_t bw ) {
385+ float notch_delay_us = 0.0 ;
386+ float bw_delay_us = 0.0 ;
387+ float tx_start_delay ;
388+
389+ /* Notch filtering performed by FPGA adds a constant delay (group delay) that we need to compensate */
390+ if (tx_notch_enable ) {
391+ notch_delay_us = lgw_fpga_get_tx_notch_delay ();
392+ }
393+
394+ /* Calibrated delay brought by SX1301 depending on signal bandwidth */
395+ switch (bw ) {
396+ case BW_125KHZ :
397+ bw_delay_us = 1.5 ;
398+ break ;
399+ case BW_500KHZ :
400+ /* Intended fall-through: it is the calibrated reference */
401+ default :
402+ break ;
403+ }
404+
405+ tx_start_delay = (float )TX_START_DELAY_DEFAULT - bw_delay_us - notch_delay_us ;
406+
407+ printf ("INFO: tx_start_delay=%u (%f) - (%u, bw_delay=%f, notch_delay=%f)\n" , (uint16_t )tx_start_delay , tx_start_delay , TX_START_DELAY_DEFAULT , bw_delay_us , notch_delay_us );
408+
409+ return (uint16_t )tx_start_delay ; /* keep truncating instead of rounding: better behaviour measured */
410+ }
411+
386412/* -------------------------------------------------------------------------- */
387413/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
388414
@@ -678,7 +704,6 @@ int lgw_start(void) {
678704 uint8_t cal_cmd ;
679705 uint16_t cal_time ;
680706 uint8_t cal_status ;
681- enum lgw_brd_version_e brd_version = LGW_BRD_VERSION_UNKNOWN ;
682707
683708 uint64_t fsk_sync_word_reg ;
684709
@@ -692,24 +717,6 @@ int lgw_start(void) {
692717 return LGW_HAL_ERROR ;
693718 }
694719
695- /* Adjust parameters which depends on the concentrator board version */
696- reg_stat = lgw_brd_version (& brd_version );
697- if ((reg_stat == LGW_REG_ERROR ) || (brd_version == LGW_BRD_VERSION_UNKNOWN )) {
698- DEBUG_MSG ("ERROR: FAIL TO GET BOARD VERSION\n" );
699- return LGW_HAL_ERROR ;
700- }
701- switch (brd_version ) {
702- case LGW_BRD_VERSION_1_0 :
703- lgw_i_tx_start_delay_us = 1495 ; /* adjusted to send Class-B beacons at 1500µs after PPS +/-1µs */
704- break ;
705- case LGW_BRD_VERSION_1_5 :
706- lgw_i_tx_start_delay_us = 1494 ; /* adjusted to send Class-B beacons at 1500µs after PPS +/-1µs */
707- break ;
708- default :
709- /* nothing to do */
710- break ;
711- }
712-
713720 /* reset the registers (also shuts the radios down) */
714721 lgw_soft_reset ();
715722
@@ -1335,6 +1342,8 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) {
13351342 uint8_t target_mix_gain = 0 ; /* used to select the proper I/Q offset correction */
13361343 uint32_t count_trig = 0 ; /* timestamp value in trigger mode corrected for TX start delay */
13371344 bool tx_allowed = false;
1345+ uint16_t tx_start_delay ;
1346+ bool tx_notch_enable = false;
13381347
13391348 /* check if the concentrator is running */
13401349 if (lgw_is_started == false) {
@@ -1396,6 +1405,14 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) {
13961405 return LGW_HAL_ERROR ;
13971406 }
13981407
1408+ /* Enable notch filter for LoRa 125kHz */
1409+ if ((pkt_data .modulation == MOD_LORA ) && (pkt_data .bandwidth == BW_125KHZ )) {
1410+ tx_notch_enable = true;
1411+ }
1412+
1413+ /* Get the TX start delay to be applied for this TX */
1414+ tx_start_delay = lgw_get_tx_start_delay (tx_notch_enable , pkt_data .bandwidth );
1415+
13991416 /* interpretation of TX power */
14001417 for (pow_index = txgain_lut .size - 1 ; pow_index > 0 ; pow_index -- ) {
14011418 if (txgain_lut .lut [pow_index ].rf_power <= pkt_data .rf_power ) {
@@ -1443,7 +1460,7 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) {
14431460 /* TX state machine must be triggered at (T0 - lgw_i_tx_start_delay_us) for packet to start being emitted at T0 */
14441461 if (pkt_data .tx_mode == TIMESTAMPED )
14451462 {
1446- count_trig = pkt_data .count_us - (uint32_t )lgw_i_tx_start_delay_us ;
1463+ count_trig = pkt_data .count_us - (uint32_t )tx_start_delay ;
14471464 buff [3 ] = 0xFF & (count_trig >> 24 );
14481465 buff [4 ] = 0xFF & (count_trig >> 16 );
14491466 buff [5 ] = 0xFF & (count_trig >> 8 );
@@ -1519,10 +1536,12 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) {
15191536 if (pkt_data .bandwidth == BW_500KHZ ) {
15201537 buff [0 ] |= 0x80 ; /* Set MSB bit to enlarge analog filter for 500kHz BW */
15211538 }
1522- else if (pkt_data .bandwidth == BW_125KHZ ){
1523- buff [0 ] |= 0x40 ; /* Set MSB-1 bit to enable digital filter for 125kHz BW */
1524- }
15251539
1540+ /* Set MSB-1 bit to enable digital filter if required */
1541+ if (tx_notch_enable == true) {
1542+ DEBUG_MSG ("INFO: Enabling TX notch filter\n" );
1543+ buff [0 ] |= 0x40 ;
1544+ }
15261545 } else if (pkt_data .modulation == MOD_FSK ) {
15271546 /* metadata 7, modulation type, radio chain selection and TX power */
15281547 buff [7 ] = (0x20 & (pkt_data .rf_chain << 5 )) | 0x10 | (0x0F & pow_index ); /* bit 4 is 1 -> FSK modulation */
@@ -1567,6 +1586,9 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) {
15671586 return LGW_HAL_ERROR ;
15681587 }
15691588
1589+ /* Configure TX start delay based on TX notch filter */
1590+ lgw_reg_w (LGW_TX_START_DELAY , tx_start_delay );
1591+
15701592 /* copy payload from user struct to buffer containing metadata */
15711593 memcpy ((void * )(buff + payload_offset ), (void * )(pkt_data .payload ), pkt_data .size );
15721594
@@ -1578,7 +1600,7 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) {
15781600 lgw_reg_wb (LGW_TX_DATA_BUF_DATA , buff , transfer_size );
15791601 DEBUG_ARRAY (i , transfer_size , buff );
15801602
1581- x = lbt_is_channel_free (& pkt_data , & tx_allowed );
1603+ x = lbt_is_channel_free (& pkt_data , tx_start_delay , & tx_allowed );
15821604 if (x != LGW_LBT_SUCCESS ) {
15831605 DEBUG_MSG ("ERROR: Failed to check channel availability for TX\n" );
15841606 return LGW_HAL_ERROR ;
0 commit comments