/** * \brief Starts the timer for the backoff period and enables receiver. */ static void start_backoff(void) { /* Start backoff timer to trigger CCA */ uint8_t backoff_8; backoff_8 = (uint8_t)rand() & ((1 << BE) - 1); if (backoff_8 > 0) { uint16_t backoff_16; uint32_t backoff_duration_us; backoff_16 = backoff_8 * aUnitBackoffPeriod; backoff_duration_us = TAL_CONVERT_SYMBOLS_TO_US(backoff_16); pal_timer_start(TAL_T_BOFF, backoff_duration_us, TIMEOUT_RELATIVE, (FUNC_PTR)cca_start, NULL); tal_state = TAL_BACKOFF; #ifdef RX_WHILE_BACKOFF /* Switch receiver on during backoff */ if (NULL == tal_rx_buffer) { set_trx_state(CMD_PLL_ON); tal_rx_on_required = true; } else { set_trx_state(CMD_RX_AACK_ON); /* receive while backoff **/ } #else set_trx_state(CMD_PLL_ON); #endif } else { /* Start CCA immediately - no backoff */ cca_start(NULL); } }
/** * @brief Starts the timer for the backoff period and enables receiver. * * @param trx_id Transceiver identifier */ static void start_backoff(trx_id_t trx_id) { /* Start backoff timer to trigger CCA */ uint8_t backoff_8; backoff_8 = (uint8_t)(rand() & (((uint16_t)1 << BE[trx_id]) - 1)); if (backoff_8 > 0) { uint8_t timer_id; uint16_t backoff_16; uint32_t backoff_duration_us; backoff_16 = backoff_8 * aUnitBackoffPeriod; backoff_duration_us = (uint32_t)tal_pib[trx_id].SymbolDuration_us * (uint32_t)backoff_16; #ifdef REDUCED_BACKOFF_DURATION backoff_duration_us = REDUCED_BACKOFF_DURATION; #endif if (trx_id == RF09) { timer_id = TAL_T_0; } else { timer_id = TAL_T_1; } retval_t status = pal_timer_start(timer_id, backoff_duration_us, TIMEOUT_RELATIVE, (FUNC_PTR)cca_start, (void *)&timer_cb_parameter[trx_id]); if (status != MAC_SUCCESS) { tx_done_handling(trx_id, status); return; } tx_state[trx_id] = TX_BACKOFF; #ifdef RX_WHILE_BACKOFF /* Keep receiver on during backoff */ if ((trx_default_state[trx_id] == RF_RX) && (tal_pib[trx_id].NumRxFramesDuringBackoff < tal_pib[trx_id].MaxNumRxFramesDuringBackoff)) { if (trx_state[trx_id] != RF_RX) { if (trx_state[trx_id] == RF_TRXOFF) { switch_to_txprep(trx_id); } switch_to_rx(trx_id); } } else #endif { #ifdef USE_TXPREP_DURING_BACKOFF /* Switch to TXPREP during backoff */ if (trx_state[trx_id] != RF_TXPREP) { switch_to_txprep(trx_id); } #else /* Switch to TRXOFF during backoff */ if (trx_state[trx_id] != RF_TRXOFF) { uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id; trx_reg_write(reg_offset + RG_RF09_CMD, RF_TRXOFF); trx_state[trx_id] = RF_TRXOFF; } #endif } } else { /* no backoff required */ /* Start CCA immediately - no backoff */ cca_start((void *)&timer_cb_parameter[trx_id]); } }