This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DTM Example Firmware Bug ?

Hi I'm setting up a firmware based on the DTM example to perform certification tests.

In the DTM example firmware I see that there is a VENDOR_SPECIFIC command option to use combined with the LE_TRANSMITTER_TEST command. The VENDOR_SPECIFIC command option has other sub-commands and I'm interested in the SET_TX_POWER one.

In the main.c code there is the uart packet parsing:

static uint32_t dtm_cmd_put(uint16_t command)
{
  dtm_cmd_t      command_code = (command >> 14) & 0x03;
  dtm_freq_t     freq         = (command >> 8) & 0x3F;
  uint32_t       length       = (command >> 2) & 0x3F;
  dtm_pkt_type_t payload      = command & 0x03;

  // Check for Vendor Specific payload.
  if (payload == 0x03) 
  {
    payload = DTM_PKT_VENDORSPECIFIC;
  }
  return dtm_cmd(command_code, freq, length, payload);
}

In the

dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload)

function there this call:

dtm_vendor_specific_pkt(length, freq);

and the function is defined as

dtm_vendor_specific_pkt(uint32_t vendor_cmd, dtm_freq_t vendor_option)

so, for VENDOR_SPECIFIC commands, the length field becomes the vendor_cmd and the freq field becomes the vendor_option (the type dtm_freq_t is defined as an uint32_t).

For the SET_TX_POWER command there is a call to

dtm_set_txpower(vendor_option)

and the function is like this:

bool dtm_set_txpower(uint32_t new_tx_power)
{
  // radio->TXPOWER register is 32 bits, low octet a signed value, upper 24 bits zeroed
  int8_t new_power8 = (int8_t)(new_tx_power & 0xFF);

  if (m_state > STATE_IDLE)
  {
    // radio must be idle to change the tx power
    return false;
  }

  if ((new_power8 > 4) || (new_power8 < -40))
  {
    // Parameter outside valid range: nRF radio is restricted to the range -40 dBm to +4 dBm
    return false;
  }

  if (new_tx_power & 0x03) 
  {
    // Parameter error: The nRF51 radio requires settings that are a multiple of 4.
    return false;
  }
  m_tx_power = new_tx_power;

  return true;
}

My question is: how the freq value (that for the SET_TX_POWER command is the new_tx_power value), can be a negative value?

freq is initially set as:

freq = (command >> 8) & 0x3F;

so freq is a 6-bit value ( 00bbbbbb )

An int8_t is a byte where the msb is the sign bit ( sbbbbbbb ), so the conversion in the function dtm_set_txpower(...) that is

int8_t new_power8 = (int8_t)(new_tx_power & 0xFF);

in my opinion, never gets a negative value for new_power8.

Related