arch/dev/radio/dw1000/dw1000-util.c
/**
 * Estimate the transmission time of a frame in nanoseconds
 * dwt_config_t   dwt_config  Configuration struct of the DW1000
 * uint16_t       framelength Framelength including the 2-Byte CRC
 * bool           only_rmarker Option to compute only the time to the RMARKER (SHR time)
 *
 *
 * Source: https://tomlankhorst.nl/estimating-decawave-dw1000-tx-time/
 */
Estimate the transmission time of a frame in nanoseconds
dwt_config_t   dwt_config  Configuration struct of the DW1000
uint16_t       framelength Framelength including the 2-Byte CRC
bool           only_rmarker Option to compute only the time to the RMARKER (SHR time)


Estimate the transmission time of a frame in nanoseconds dwt_config_t dwt_config Configuration struct of the DW1000 uint16_t framelength Framelength including the 2 - Byte CRC bool only_rmarker Option to compute only the time to the RMARKER ( SHR time )
uint32_t
dw1000_estimate_tx_time(const dwt_config_t* dwt_config, uint16_t framelength, bool only_rmarker)
{
  uint32_t tx_time      = 0;
  size_t sym_timing_ind = 0;
  uint16_t shr_len      = 0;
  const uint16_t DATA_BLOCK_SIZE  = 330;
  const uint16_t REED_SOLOM_BITS  = 48;
  const size_t SYM_TIM_16MHZ = 0;
  const size_t SYM_TIM_64MHZ = 9;
  const size_t SYM_TIM_110K  = 0;
  const size_t SYM_TIM_850K  = 3;
  const size_t SYM_TIM_6M8   = 6;
  const size_t SYM_TIM_SHR   = 0;
  const size_t SYM_TIM_PHR   = 1;
  const size_t SYM_TIM_DAT   = 2;
  const static uint16_t SYM_TIM_LUT[] = {
    994, 8206, 8206,  
    994, 1026, 1026,  
    994, 1026, 129,   
    1018, 8206, 8206, 
    1018, 1026, 1026, 
    1018, 1026, 129   
  };
  switch( dwt_config->prf ) {
    case DWT_PRF_16M:  sym_timing_ind = SYM_TIM_16MHZ; break;
    case DWT_PRF_64M:  sym_timing_ind = SYM_TIM_64MHZ; break;
  }
  switch( dwt_config->txPreambLength ) {
    case DWT_PLEN_64:    shr_len = 64;    break;
    case DWT_PLEN_128:   shr_len = 128;   break;
    case DWT_PLEN_256:   shr_len = 256;   break;
    case DWT_PLEN_512:   shr_len = 512;   break;
    case DWT_PLEN_1024:  shr_len = 1024;  break;
    case DWT_PLEN_1536:  shr_len = 1536;  break;
    case DWT_PLEN_2048:  shr_len = 2048;  break;
    case DWT_PLEN_4096:  shr_len = 4096;  break;
  }
  switch( dwt_config->dataRate ) {
    case DWT_BR_110K:
      sym_timing_ind  += SYM_TIM_110K;
      shr_len         += 64;  
      break;
    case DWT_BR_850K:
      sym_timing_ind  += SYM_TIM_850K;
      shr_len         += 8;   
      break;
    case DWT_BR_6M8:
      sym_timing_ind  += SYM_TIM_6M8;
      shr_len         += 8;   
      break;
  }
  tx_time   = shr_len * SYM_TIM_LUT[ sym_timing_ind + SYM_TIM_SHR ];
  if( !only_rmarker ) {
    tx_time  += 21 * SYM_TIM_LUT[ sym_timing_ind + SYM_TIM_PHR ];
    framelength *= 8;
    framelength += REED_SOLOM_BITS * ( framelength + DATA_BLOCK_SIZE - 1 ) / DATA_BLOCK_SIZE;
    tx_time += framelength * SYM_TIM_LUT[ sym_timing_ind + SYM_TIM_DAT ];
  }
  return tx_time;
}
uint32_t dw1000_estimate_tx_time ( const dwt_config_t * dwt_config , uint16_t framelength , bool only_rmarker ) { uint32_t tx_time = 0 ; size_t sym_timing_ind = 0 ; uint16_t shr_len = 0 ; const uint16_t DATA_BLOCK_SIZE = 330 ; const uint16_t REED_SOLOM_BITS = 48 ; const size_t SYM_TIM_16MHZ = 0 ; const size_t SYM_TIM_64MHZ = 9 ; const size_t SYM_TIM_110K = 0 ; const size_t SYM_TIM_850K = 3 ; const size_t SYM_TIM_6M8 = 6 ; const size_t SYM_TIM_SHR = 0 ; const size_t SYM_TIM_PHR = 1 ; const size_t SYM_TIM_DAT = 2 ; const static uint16_t SYM_TIM_LUT [ ] = { 994 , 8206 , 8206 , 994 , 1026 , 1026 , 994 , 1026 , 129 , 1018 , 8206 , 8206 , 1018 , 1026 , 1026 , 1018 , 1026 , 129 } ; switch ( dwt_config -> prf ) { case DWT_PRF_16M : sym_timing_ind = SYM_TIM_16MHZ ; break ; case DWT_PRF_64M : sym_timing_ind = SYM_TIM_64MHZ ; break ; } switch ( dwt_config -> txPreambLength ) { case DWT_PLEN_64 : shr_len = 64 ; break ; case DWT_PLEN_128 : shr_len = 128 ; break ; case DWT_PLEN_256 : shr_len = 256 ; break ; case DWT_PLEN_512 : shr_len = 512 ; break ; case DWT_PLEN_1024 : shr_len = 1024 ; break ; case DWT_PLEN_1536 : shr_len = 1536 ; break ; case DWT_PLEN_2048 : shr_len = 2048 ; break ; case DWT_PLEN_4096 : shr_len = 4096 ; break ; } switch ( dwt_config -> dataRate ) { case DWT_BR_110K : sym_timing_ind += SYM_TIM_110K ; shr_len += 64 ; break ; case DWT_BR_850K : sym_timing_ind += SYM_TIM_850K ; shr_len += 8 ; break ; case DWT_BR_6M8 : sym_timing_ind += SYM_TIM_6M8 ; shr_len += 8 ; break ; } tx_time = shr_len * SYM_TIM_LUT [ sym_timing_ind + SYM_TIM_SHR ] ; if ( ! only_rmarker ) { tx_time += 21 * SYM_TIM_LUT [ sym_timing_ind + SYM_TIM_PHR ] ; framelength *= 8 ; framelength += REED_SOLOM_BITS * ( framelength + DATA_BLOCK_SIZE - 1 ) / DATA_BLOCK_SIZE ; tx_time += framelength * SYM_TIM_LUT [ sym_timing_ind + SYM_TIM_DAT ] ; } return tx_time ; }
Estimate the transmission time of a frame in nanoseconds
 dwt_config_t   dwt_config  Configuration struct of the DW1000
 uint16_t       framelength Framelength including the 2-Byte CRC
 bool           only_rmarker Option to compute only the time to the RMARKER (SHR time)
Estimate the transmission time of a frame in nanoseconds dwt_config_t dwt_config Configuration struct of the DW1000 uint16_t framelength Framelength including the 2 - Byte CRC bool only_rmarker Option to compute only the time to the RMARKER ( SHR time )
// Symbol timing LUT // 16 Mhz PRF // 0.11 Mbps // 0.85 Mbps // 6.81 Mbps // 64 Mhz PRF // 0.11 Mbps // 0.85 Mbps // 6.81 Mbps // Find the PHR // Find the preamble length // Find the datarate // SFD 64 symbols // SFD 8 symbols // SFD 8 symbols // Add the SHR time // If not only RMARKER, calculate PHR and data // Add the PHR time (21 bits) // Bytes to bits // Add Reed-Solomon parity bits // Add the DAT time // Return in nano seconds