如题,使用NRF52832或者NRF52840的私有2.4G协议时,可以控制发送的数据是否启用自动ack
,有两个关键变量,一个是初始化时的配置,另一个是发送数据时数据包中的配置。分别如下
bool selective_auto_ack; //!< Enable or disable selective auto acknowledgement.xxxxxxxxxx2 1nrf_esb_config.selective_auto_ack bool selective_auto_ack; //!< Enable or disable selective auto acknowledgement.2
typedef struct
{
uint8_t length; //!< Length of the packet (maximum value is @ref NRF_ESB_MAX_PAYLOAD_LENGTH).
uint8_t pipe; //!< Pipe used for this payload.
int8_t rssi; //!< RSSI for the received packet.
uint8_t noack; //!< Flag indicating that this packet will not be acknowledgement.
uint8_t pid; //!< PID assigned during communication.
uint8_t data[NRF_ESB_MAX_PAYLOAD_LENGTH]; //!< The payload data.
} nrf_esb_payload_t;
查看源代码,开始发送函数start_tx_transaction
内部对于是否ack发送的操作是不一样的,区分两者操作是通过一个ack
变量来确定
static void start_tx_transaction()
{
bool ack;
m_last_tx_attempts = 1;
// Prepare the payload
mp_current_payload = m_tx_fifo.p_payload[m_tx_fifo.exit_point];
switch (m_config_local.protocol)
{
case NRF_ESB_PROTOCOL_ESB:
update_rf_payload_format(mp_current_payload->length);
m_tx_payload_buffer[0] = mp_current_payload->pid;
m_tx_payload_buffer[1] = 0;
memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length);
NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_RXEN_Msk;
NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk;
// Configure the retransmit counter
m_retransmits_remaining = m_config_local.retransmit_count;
on_radio_disabled = on_radio_disabled_tx;
m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK;
break;
case NRF_ESB_PROTOCOL_ESB_DPL:
ack = !mp_current_payload->noack || !m_config_local.selective_auto_ack;
m_tx_payload_buffer[0] = mp_current_payload->length;
m_tx_payload_buffer[1] = mp_current_payload->pid << 1;
m_tx_payload_buffer[1] |= mp_current_payload->noack ? 0x00 : 0x01;
memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length);
// Handling ack if noack is set to false or if selective auto ack is turned off
if (ack)
{
NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_RXEN_Msk;
NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk;
// Configure the retransmit counter
m_retransmits_remaining = m_config_local.retransmit_count;
on_radio_disabled = on_radio_disabled_tx;
m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK;
}
else
{
NRF_RADIO->SHORTS = m_radio_shorts_common;
NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
on_radio_disabled = on_radio_disabled_tx_noack;
m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX;
}
break;
default:
// Should not be reached
break;
}
NRF_RADIO->TXADDRESS = mp_current_payload->pipe;
NRF_RADIO->RXADDRESSES = 1 << mp_current_payload->pipe;
NRF_RADIO->FREQUENCY = m_esb_addr.rf_channel;
NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer;
NVIC_ClearPendingIRQ(RADIO_IRQn);
NVIC_EnableIRQ(RADIO_IRQn);
NRF_RADIO->EVENTS_ADDRESS = 0;
NRF_RADIO->EVENTS_PAYLOAD = 0;
NRF_RADIO->EVENTS_DISABLED = 0;
DEBUG_PIN_SET(DEBUGPIN4);
NRF_RADIO->TASKS_TXEN = 1;
}
注意 第28行 ack变量的取值
ack = !mp_current_payload->noack || !m_config_local.selective_auto_ack;
当初始化2.4G时,设置selective_auto_ack
为true
时,整个表达式会根据发数据数据包中的noack
变量取值改变而改变,当selective_auto_ack
为false
时,ack
都为true
,noack
无效,
selective_auto_ack | noack | ack |
---|---|---|
true | true | false |
true | false | true |
false | x | true |
也就是说只有selective_auto_ack
为true,才可以设置数据包是否启用自动ack,noack为true时,不启用,noack为false时,启用
另外设置pipe个数为是通过下列函数指定的,第二个参数确定开启几个pipe
err_code = nrf_esb_set_prefixes(addr_prefix, NRF_ESB_PIPE_COUNT);