349 lines
13 KiB
C
349 lines
13 KiB
C
/* Copyright (c) 2016, Nordic Semiconductor ASA
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @brief This module contains generic 802.15.4 radio driver for nRF SoC devices.
|
|
*
|
|
*/
|
|
|
|
#ifndef NRF_RADIO802154_H_
|
|
#define NRF_RADIO802154_H_
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Initialize 802.15.4 driver.
|
|
*
|
|
* @note This function shall be called once, before any other function from this module.
|
|
*
|
|
* Initialize radio peripheral to Sleep state.
|
|
*/
|
|
void nrf_drv_radio802154_init(void);
|
|
|
|
/**
|
|
* @brief Get channel on which the radio operates right now.
|
|
*/
|
|
uint8_t nrf_drv_radio802154_channel_get(void);
|
|
|
|
/**
|
|
* @section Setting addresses and Pan Id of this device.
|
|
*/
|
|
|
|
/**
|
|
* @brief Set PAN Id used by this device.
|
|
*
|
|
* @param[in] p_pan_id Pointer to PAN Id (2 bytes, little-endian).
|
|
*
|
|
* This function makes copy of the PAN Id.
|
|
*/
|
|
void nrf_drv_radio802154_pan_id_set(const uint8_t *p_pan_id);
|
|
|
|
/**
|
|
* @brief Set Extended Address of this device.
|
|
*
|
|
* @param[in] p_extended_address Pointer to extended address (8 bytes, little-endian).
|
|
*
|
|
* This function makes copy of the address.
|
|
*/
|
|
void nrf_drv_radio802154_extended_address_set(const uint8_t *p_extended_address);
|
|
|
|
/**
|
|
* @brief Set Short Address of this device.
|
|
*
|
|
* @param[in] p_short_address Pointer to short address (2 bytes, little-endian).
|
|
*
|
|
* This function makes copy of the address.
|
|
*/
|
|
void nrf_drv_radio802154_short_address_set(const uint8_t *p_short_address);
|
|
|
|
|
|
/**
|
|
* @section Functions to request FSM transitions.
|
|
*
|
|
* receive() transmit()
|
|
* --------> -------->
|
|
* Sleep Receive Transmit
|
|
* <-------- | /|\<--------
|
|
* sleep() | | receive() / transmitted() / busy_channel()
|
|
* | |
|
|
* energy_detection() | | energy_detected()
|
|
* \|/ |
|
|
* Energy detection
|
|
*/
|
|
|
|
/**
|
|
* @brief Change radio state to Sleep.
|
|
*
|
|
* @note This function should be called only if radio is in Receive state.
|
|
*
|
|
* Sleep state is the lowest power state. In this state radio cannot transmit or receive frames.
|
|
*
|
|
* @return true If the radio changes it's state to low power mode.
|
|
* @return false If the driver could not schedule changing state.
|
|
*/
|
|
bool nrf_drv_radio802154_sleep(void);
|
|
|
|
/**
|
|
* @brief Change radio state to Receive.
|
|
*
|
|
* @note This function should be called in Sleep or Transmit state.
|
|
*
|
|
* In Receive state radio receives frames and automatically sends ACK frames when appropriate.
|
|
* Received frame is reported to higher layer by nrf_radio802154_received() call.
|
|
*
|
|
* @param[in] channel Channel number on which radio will receive.
|
|
* @param[in] force_rx If set to true then function is allowed to stop an ongoing
|
|
* operation. If set to false then the function will succeed
|
|
* only when radio is in RX or SLEEP state.
|
|
*
|
|
* @return true If the reception procedure was scheduled.
|
|
* @return false If the driver could not schedule the reception procedure.
|
|
*/
|
|
bool nrf_drv_radio802154_receive(uint8_t channel, bool force_rx);
|
|
|
|
/**
|
|
* @brief Change radio state to Transmit.
|
|
*
|
|
* @note This function should be called in Receive state. In other states transmission will be
|
|
* scheduled.
|
|
*
|
|
* In Transmit state radio transmits given frame. If requested it waits for ACK frame.
|
|
* Radio driver wait infinitely for ACK frame. Higher layer is responsible to call
|
|
* nrf_radio802154_receive() after ACK timeout.
|
|
* Transmission result is reported to higher layer by nrf_radio802154_transmitted() or
|
|
* nrf_radio802154_busy_channel() calls.
|
|
*
|
|
* @param[in] p_data Pointer to array containing data to transmit. First byte should contain
|
|
* frame length and following bytes should contain data. CRC is computed
|
|
* automatically by radio hardware and can contain any bytes.
|
|
* @param[in] channel Channel number on which radio will transmit given frame.
|
|
* @param[in] power Transmission power [dBm]. Given value is rounded up to nearest permitted
|
|
* value.
|
|
*
|
|
* @return true If the transmission procedure was scheduled.
|
|
* @return false If the driver could not schedule the transmission procedure.
|
|
*/
|
|
bool nrf_drv_radio802154_transmit(const uint8_t *p_data, uint8_t channel, int8_t power);
|
|
|
|
/**
|
|
* @brief Change radio state to Energy Detection.
|
|
*
|
|
* @note This function should be called in Receive state. In other states energy detection
|
|
* procedure will be scheduled.
|
|
*
|
|
* In Energy Detection state radio detects maximum energy for given time. Result of the detection
|
|
* is reported to the higher layer by nrf_radio802154_energy_detected() call.
|
|
*
|
|
* @param[in] channel Channel number on which radio will detect energy.
|
|
* @param[in] time_us Duration of energy detection procedure. Given value is rounded up to
|
|
* multiplication of 10s (128 us).
|
|
*
|
|
* @return true If the energy detection procedure was scheduled.
|
|
* @return false If the driver could not schedule the energy detection procedure.
|
|
*/
|
|
bool nrf_drv_radio802154_energy_detection(uint8_t channel, uint32_t time_us);
|
|
|
|
|
|
/**
|
|
* @section Calls to higher layer.
|
|
*/
|
|
|
|
/**
|
|
* @brief Notify that frame was received.
|
|
*
|
|
* @note Buffer pointed by the p_data pointer is not modified by the radio driver (and can't
|
|
* be used to receive a frame) until nrf_drv_radio802154_buffer_free() function is called.
|
|
* @note Buffer pointed by the p_data pointer may be modified by the function handler (and other
|
|
* modules) until nrf_drv_radio802154_buffer_free() function is called.
|
|
*
|
|
* @param[in] p_data Pointer to buffer containing received data. First byte in the buffer is
|
|
* length of the frame and following bytes is the frame itself (after PHR).
|
|
* @param[in] power RSSI of received frame.
|
|
* @param[in] lqi LQI of received frame.
|
|
*/
|
|
void nrf_drv_radio802154_received(uint8_t * p_data, int8_t power, int8_t lqi);
|
|
|
|
/**
|
|
* @brief Notify that frame was transmitted.
|
|
*
|
|
* @note If ACK was requested for transmitted frame this function is called after proper ACK is
|
|
* received. If ACK was not requested this function is called just after transmission is
|
|
* ended.
|
|
*
|
|
* @param[in] pending_bit Value of pending bit in received ACK or false if ACK was not requested.
|
|
*/
|
|
void nrf_drv_radio802154_transmitted(bool pending_bit);
|
|
|
|
/**
|
|
* @brief Notify that frame was not transmitted due to busy channel.
|
|
*
|
|
* This function is called if CCA procedure (performed just before transmission) fails.
|
|
*/
|
|
void nrf_drv_radio802154_busy_channel(void);
|
|
|
|
/**
|
|
* @brief Notify that Energy Detection procedure finished.
|
|
*
|
|
* @param[in] result Maximum energy detected during Energy Detection procedure.
|
|
*/
|
|
void nrf_drv_radio802154_energy_detected(int8_t result);
|
|
|
|
|
|
/**
|
|
* @section Driver memory management
|
|
*/
|
|
|
|
/**
|
|
* @brief Notify driver that buffer containing received frame is not used anymore.
|
|
*
|
|
* @note The buffer pointed by the @p p_data pointer may be modified by this function.
|
|
*
|
|
* @param[in] p_data A pointer to the buffer containing received data that is no more needed by
|
|
* the higher layer.
|
|
*/
|
|
void nrf_drv_radio802154_buffer_free(uint8_t * p_data);
|
|
|
|
|
|
/**
|
|
* @section RSSI measurement function.
|
|
*/
|
|
|
|
/**
|
|
* @brief Begin RSSI measurement.
|
|
*
|
|
* @note This function should be called in Receive state.
|
|
*
|
|
* Begin RSSI measurement. The result will be available in 8 uS. The result can be read by
|
|
* nrf_radio802154_rssi_last_get() function.
|
|
*/
|
|
void nrf_drv_radio802154_rssi_measure(void);
|
|
|
|
/**
|
|
* @brief Get result of last RSSI measurement.
|
|
*
|
|
* @returns RSSI measurement result [dBm].
|
|
*/
|
|
int8_t nrf_drv_radio802154_rssi_last_get(void);
|
|
|
|
|
|
/**
|
|
* @section Promiscuous mode.
|
|
*/
|
|
|
|
/**
|
|
* @brief Enable or disable promiscuous radio mode.
|
|
*
|
|
* In promiscuous mode driver notifies higher layer that it received any frame (regardless
|
|
* frame type or destination address).
|
|
* In normal mode (not promiscuous) higher layer is not notified about ACK frames and frames with
|
|
* unknown type. Also frames with destination address not matching this device address are ignored.
|
|
*
|
|
* @param[in] enabled If promiscuous mode should be enabled.
|
|
*/
|
|
void nrf_drv_radio802154_promiscuous_set(bool enabled);
|
|
|
|
/**
|
|
* @brief Check if radio is in promiscuous mode.
|
|
*
|
|
* @retval True Radio is in promiscuous mode.
|
|
* @retval False Radio is not in promiscuous mode.
|
|
*/
|
|
bool nrf_drv_radio802154_promiscuous_get(void);
|
|
|
|
|
|
/**
|
|
* @section Setting pending bit in automatically transmitted ACK frames.
|
|
*/
|
|
|
|
/**
|
|
* @brief Enable or disable setting pending bit in automatically transmitted ACK frames.
|
|
*
|
|
* Radio driver automatically sends ACK frames in response to unicast frames destined to this node.
|
|
* Pending bit in ACK frame can be set or cleared regarding data in pending buffer destined to ACK
|
|
* destination.
|
|
*
|
|
* If setting pending bit in ACK frames is disabled, pending bit in every ACK frame is set.
|
|
* If setting pending bit in ACK frames is enabled, radio driver checks if there is data
|
|
* in pending buffer destined to ACK destination. If there is no such data, pending bit is cleared.
|
|
*
|
|
* @note It is possible that if there is a lot of supported peers radio driver cannot verify
|
|
* if there is pending data before ACK is sent. In this case pending bit is set.
|
|
*
|
|
* @param[in] enabled If setting pending bit in ACK frames is enabled.
|
|
*/
|
|
void nrf_drv_radio802154_auto_pending_bit_set(bool enabled);
|
|
|
|
/**
|
|
* @brief Add address of peer node for which there is pending data in the buffer.
|
|
*
|
|
* @note This function makes a copy of given address.
|
|
*
|
|
* @param[in] p_addr Array of bytes containing address of the node (little-endian).
|
|
* @param[in] extended If given address is Extended MAC Address or Short MAC Address.
|
|
*
|
|
* @retval True Address successfully added to the list.
|
|
* @retval False There is not enough memory to store this address in the list.
|
|
*/
|
|
bool nrf_drv_radio802154_pending_bit_for_addr_set(const uint8_t *p_addr, bool extended);
|
|
|
|
/**
|
|
* @brief Remove address of peer node for which there is no more pending data in the buffer.
|
|
*
|
|
* @param[in] p_addr Array of bytes containing address of the node (little-endian).
|
|
* @param[in] extended If given address is Extended MAC Address or Short MAC Address.
|
|
*
|
|
* @retval True Address successfully removed from the list.
|
|
* @retval False There is no such address in the list.
|
|
*/
|
|
bool nrf_drv_radio802154_pending_bit_for_addr_clear(const uint8_t *p_addr, bool extended);
|
|
|
|
/**
|
|
* @brief Remove all addresses of given type from pending bit list.
|
|
*
|
|
* @param[in] extended If function should remove all Exnteded MAC Adresses of all Short Addresses.
|
|
*/
|
|
void nrf_drv_radio802154_pending_bit_for_addr_reset(bool extended);
|
|
|
|
/**
|
|
* @brief Radio IRQ handler.
|
|
*/
|
|
void nrf_drv_radio802154_irq_handler(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* NRF_RADIO802154_H_ */
|