I’m running the following experiment to test that I am correctly assigning and switching channels:
-2 devices.
-1 device transmits 1 packet periodically, each time on a different channel. Specifically, the device will transmit on channel 1 then 4, 5, 7, 3, and 2 before starting back over with 1. This is done continuously
- The other device is continuously listening on ONLY channel 1.
It is my expectation that out of the repeated period (i.e running through all channels once), only one packet will be received by the receiver (on channel 1). However, the receiver is actually receiving three packets over the interval before starting over from channels 3,2,1; in that order (no packets received from 4, 5, or 7). This is despite the fact that the receiver is ONLY listening to channel 1. The code I am using to switch channels is at the end of this post (most of it was copied from the dwt_configure function with substituted variables). The code is called directly before starting to either transmit or receive (e.g. directly before calling dwt_rxenable(DWT_START_RX_IMMEDIATE))
Things I’ve tried:
- removed the tx power changes that the function makes. No effect.
- tried different devices. No effect.
- increased the amount of time between subsequent packet transmissions. No effect
- stopped changing the channels and repeated the experiment using only channel 1for both devices, only channel 2 for both devices, etc. This worked as expected. The receiver received all packets that it was supposed to (in this case, all).
I’m at a loss as to why I’m receiving on channels I’m not listening to. If anyone has an idea of what’s going on or could point me the direction of a possible solution I would much appreciate it.
My best guess at this point is that either (1) I’m misunderstanding what channels mean on this device (e.g. channels are not completely isolated from each other), (2) There is a configuration wrong somewhere in the code below, or (3) it takes a very long time to switch channels and I’m not giving the device enough time to switch before transmitting.
Configuration used (note that dwt_setsmarttxpower(0) is ran after initialization and configuration)
static dwt_config_t defaultConfig_dwConfig = {
1, // starting channel. Won’t be used, just filler
DWT_PRF_64M,
DWT_PLEN_1024,
DWT_PAC32,
9, // for tx preamble code
9, // for rx preamble code
0,
DWT_BR_110K,
DWT_PHRMODE_STD,
(4096+64)
};
Code used to change channels
typedef struct ChIndex
{
// channel to use
uint8_t channel_uint8;
// preamble code
uint8_t preambleCode_uint8;
} t_ChIndex
static t_ChIndex chIndexConfigs_ChIndexArray[] = {{.channel_uint8=1, .preambleCode_uint8=9}, {.channel_uint8=4, .preambleCode_uint8=17}, {.channel_uint8=5, .preambleCode_uint8=9}, {.channel_uint8=7, .preambleCode_uint8=17}, {.channel_uint8=3, .preambleCode_uint8=9}, {.channel_uint8=2, .preambleCode_uint8=9}};
void
App_Config_Change_Channel_Index(uint8_t channelIndex_uint8, uint8_t powerLevel_uint8)
{
// make sure that the given channel index is valid
if(channelIndex_uint8 >= APP_CONFIG_NUM_VALID_CHANNELS)
{
APP_CONFIG_ERROR(APP_CONFIG_ERROR_INVALID_CHANNEL_INDEX_HOP);
}
// make sure that the power level is valid
if(powerLevel_uint8 >= 62)
{
APP_CONFIG_ERROR(APP_CONFIG_ERROR_INVALID_POWER_LEVEL);
}
// reconfigure the radio for the new channel
uint8_t channel_uint8 = chIndexConfigs_ChIndexArray[channelIndex_uint8].channel_uint8;
uint8_t preambleCode_uint8 = chIndexConfigs_ChIndexArray[channelIndex_uint8].preambleCode_uint8;
dwt_write32bitoffsetreg(FS_CTRL_ID, FS_PLLCFG_OFFSET, fs_pll_cfg[chan_idx[channel_uint8]]);
dwt_write8bitoffsetreg(FS_CTRL_ID, FS_PLLTUNE_OFFSET, fs_pll_tune[chan_idx[channel_uint8]]);
dwt_write8bitoffsetreg(RF_CONF_ID, RF_RXCTRLH_OFFSET, rx_config[((channel_uint8 == 4) || (channel_uint8 == 7)) ? 1 : 0]);
dwt_write32bitoffsetreg(RF_CONF_ID, RF_TXCTRL_OFFSET, tx_config[chan_idx[channel_uint8]]);
#if APP_CONFIG_DW_SFD_TYPE
dwt_write32bitreg(CHAN_CTRL_ID, (CHAN_CTRL_TX_CHAN_MASK & (channel_uint8 << CHAN_CTRL_TX_CHAN_SHIFT)) |
(CHAN_CTRL_RX_CHAN_MASK & (channel_uint8 << CHAN_CTRL_RX_CHAN_SHIFT)) |
(CHAN_CTRL_RXFPRF_MASK & (APP_CONFIG_DW_DEFAULT_PULSE_FREQ << CHAN_CTRL_RXFPRF_SHIFT)) |
((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (3 << CHAN_CTRL_TNSSFD_SHIFT)) |
(CHAN_CTRL_DWSFD & (1 << CHAN_CTRL_DWSFD_SHIFT)) |
(CHAN_CTRL_TX_PCOD_MASK & (preambleCode_uint8 << CHAN_CTRL_TX_PCOD_SHIFT)) |
(CHAN_CTRL_RX_PCOD_MASK & (preambleCode_uint8 << CHAN_CTRL_RX_PCOD_SHIFT)));
#else
dwt_write32bitreg(CHAN_CTRL_ID, (CHAN_CTRL_TX_CHAN_MASK & (channel_uint8 << CHAN_CTRL_TX_CHAN_SHIFT)) |
(CHAN_CTRL_RX_CHAN_MASK & (channel_uint8 << CHAN_CTRL_RX_CHAN_SHIFT)) |
(CHAN_CTRL_RXFPRF_MASK & (APP_CONFIG_DW_DEFAULT_PULSE_FREQ << CHAN_CTRL_RXFPRF_SHIFT)) |
((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (0 << CHAN_CTRL_TNSSFD_SHIFT)) |
(CHAN_CTRL_DWSFD & (0 << CHAN_CTRL_DWSFD_SHIFT)) |
(CHAN_CTRL_TX_PCOD_MASK & (preambleCode_uint8 << CHAN_CTRL_TX_PCOD_SHIFT)) |
(CHAN_CTRL_RX_PCOD_MASK & (preambleCode_uint8 << CHAN_CTRL_RX_PCOD_SHIFT)));
#endif
// configure the tx power levels
//dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, pgDelays_uint8Array[chan_idx[channel_uint8]]);
//dwt_write32bitreg(TX_POWER_ID, txPowerLevels_uint32Array[powerLevel_uint8]);
printf("%d\n", channel_uint8);
}