NRF52832 NRF52840 私有2.4G无线ESB协议控制是否ACK操作

如题,使用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_acktrue时,整个表达式会根据发数据数据包中的noack变量取值改变而改变,当selective_auto_ackfalse时,ack都为truenoack无效,

selective_auto_acknoackack
truetruefalse
truefalsetrue
falsextrue

也就是说只有selective_auto_ack为true,才可以设置数据包是否启用自动ack,noack为true时,不启用,noack为false时,启用

另外设置pipe个数为是通过下列函数指定的,第二个参数确定开启几个pipe

  err_code = nrf_esb_set_prefixes(addr_prefix, NRF_ESB_PIPE_COUNT);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值