1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #7568 from gebart/pr/at86rf2xx-cca

at86rf2xx: Add manual CCA
This commit is contained in:
Sebastian Meiling 2017-09-06 17:19:51 +02:00 committed by GitHub
commit 96822ffe3d
4 changed files with 60 additions and 2 deletions

View File

@ -180,3 +180,31 @@ void at86rf2xx_tx_exec(at86rf2xx_t *dev)
netdev->event_callback(netdev, NETDEV_EVENT_TX_STARTED);
}
}
bool at86rf2xx_cca(at86rf2xx_t *dev)
{
uint8_t reg;
uint8_t old_state = at86rf2xx_set_state(dev, AT86RF2XX_STATE_TRX_OFF);
/* Disable RX path */
uint8_t rx_syn = at86rf2xx_reg_read(dev, AT86RF2XX_REG__RX_SYN);
reg = rx_syn | AT86RF2XX_RX_SYN__RX_PDT_DIS;
at86rf2xx_reg_write(dev, AT86RF2XX_REG__RX_SYN, reg);
/* Manually triggered CCA is only possible in RX_ON (basic operating mode) */
at86rf2xx_set_state(dev, AT86RF2XX_STATE_RX_ON);
/* Perform CCA */
reg = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_CC_CCA);
reg |= AT86RF2XX_PHY_CC_CCA_MASK__CCA_REQUEST;
at86rf2xx_reg_write(dev, AT86RF2XX_REG__PHY_CC_CCA, reg);
/* Spin until done (8 symbols + 12 µs = 128 µs + 12 µs for O-QPSK)*/
do {
reg = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATUS);
} while ((reg & AT86RF2XX_TRX_STATUS_MASK__CCA_DONE) == 0);
/* return true if channel is clear */
bool ret = !!(reg & AT86RF2XX_TRX_STATUS_MASK__CCA_STATUS);
/* re-enable RX */
at86rf2xx_reg_write(dev, AT86RF2XX_REG__RX_SYN, rx_syn);
/* Step back to the old state */
at86rf2xx_set_state(dev, AT86RF2XX_STATE_TRX_OFF);
at86rf2xx_set_state(dev, old_state);
return ret;
}

View File

@ -334,6 +334,12 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len)
res = sizeof(int8_t);
break;
case NETOPT_IS_CHANNEL_CLR:
assert(max_len >= sizeof(netopt_enable_t));
*((netopt_enable_t *)val) = at86rf2xx_cca(dev);
res = sizeof(netopt_enable_t);
break;
default:
res = -ENOTSUP;
break;

View File

@ -288,6 +288,15 @@ extern "C" {
#define AT86RF2XX_XOSC_CTRL__XTAL_MODE_EXTERNAL (0xF0)
/** @} */
/**
* @name Bitfield definitions for the RX_SYN register
* @{
*/
#define AT86RF2XX_RX_SYN__RX_PDT_DIS (0x80)
#define AT86RF2XX_RX_SYN__RX_OVERRIDE (0x70)
#define AT86RF2XX_RX_SYN__RX_PDT_LEVEL (0x0F)
/** @} */
/**
* @name Timing values
* @{

View File

@ -96,12 +96,15 @@ extern "C" {
* @{
*/
#define AT86RF2XX_STATE_P_ON (0x00) /**< initial power on */
#define AT86RF2XX_STATE_BUSY_RX (0x01) /**< busy receiving data (basic mode) */
#define AT86RF2XX_STATE_BUSY_TX (0x02) /**< busy transmitting data (basic mode) */
#define AT86RF2XX_STATE_FORCE_TRX_OFF (0x03) /**< force transition to idle */
#define AT86RF2XX_STATE_RX_ON (0x06) /**< listen mode (basic mode) */
#define AT86RF2XX_STATE_TRX_OFF (0x08) /**< idle */
#define AT86RF2XX_STATE_PLL_ON (0x09) /**< ready to transmit */
#define AT86RF2XX_STATE_SLEEP (0x0f) /**< sleep mode */
#define AT86RF2XX_STATE_BUSY_RX_AACK (0x11) /**< busy receiving data */
#define AT86RF2XX_STATE_BUSY_TX_ARET (0x12) /**< busy transmitting data */
#define AT86RF2XX_STATE_BUSY_RX_AACK (0x11) /**< busy receiving data (extended mode) */
#define AT86RF2XX_STATE_BUSY_TX_ARET (0x12) /**< busy transmitting data (extended mode) */
#define AT86RF2XX_STATE_RX_AACK_ON (0x16) /**< wait for incoming data */
#define AT86RF2XX_STATE_TX_ARET_ON (0x19) /**< ready for sending data */
#define AT86RF2XX_STATE_IN_PROGRESS (0x1f) /**< ongoing state conversion */
@ -431,6 +434,18 @@ size_t at86rf2xx_tx_load(at86rf2xx_t *dev, uint8_t *data, size_t len,
*/
void at86rf2xx_tx_exec(at86rf2xx_t *dev);
/**
* @brief Perform one manual channel clear assessment (CCA)
*
* The CCA mode and threshold level depends on the current transceiver settings.
*
* @param[in] dev device to use
*
* @return true if channel is determined clear
* @return false if channel is determined busy
*/
bool at86rf2xx_cca(at86rf2xx_t *dev);
#ifdef __cplusplus
}
#endif