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

nrf802154: implement CCA

This commit is contained in:
Jose Alamos 2020-01-16 16:33:29 +01:00
parent 09c79f07e7
commit f652564eb1
2 changed files with 96 additions and 2 deletions

View File

@ -42,6 +42,23 @@
extern "C" {
#endif
/**
* @defgroup drivers_nrf52_802154_conf nrf802154 driver compile configuration
* @ingroup drivers_nrf52_802154
* @ingroup config
* @{
*/
/**
* @brief NRF802154 default CCA threshold value for CCACTRL register.
*
* @note This value was copied from the Nordic reference driver configuration
*/
#ifndef CONFIG_NRF802154_CCA_THRESH_DEFAULT
#define CONFIG_NRF802154_CCA_THRESH_DEFAULT 0x14
#endif
/** @} */
/**
* @brief Export the netdev device descriptor
*/

View File

@ -17,6 +17,7 @@
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Dimitri Nahm <dimitri.nahm@haw-hamburg.de>
* @author Semjon Kerner <semjon.kerner@fu-berlin.de>
* @author José I. Alamos <jose.alamos@haw-hamburg.de>
* @}
*/
@ -120,6 +121,63 @@ static void _enable_tx(void)
DEBUG("[nrf802154] Device state: TXIDLE\n");
}
/**
* @brief Convert from dBm to the internal representation, when the
* radio operates as a IEEE802.15.4 transceiver.
*/
static inline uint8_t _dbm_to_ieee802154_hwval(int8_t dbm)
{
return ((dbm - ED_RSSIOFFS) / ED_RSSISCALE);
}
/**
* @brief Convert from the internal representation to dBm, when the
* radio operates as a IEEE802.15.4 transceiver.
*/
static inline int8_t _hwval_to_ieee802154_dbm(uint8_t hwval)
{
return (ED_RSSISCALE * hwval) + ED_RSSIOFFS;
}
/**
* @brief Get CCA threshold value in internal represetion
*/
static int _get_cca_thresh(void)
{
return (NRF_RADIO->CCACTRL & RADIO_CCACTRL_CCAEDTHRES_Msk) >>
RADIO_CCACTRL_CCAEDTHRES_Pos;
}
/**
* @brief Set CCA threshold value in internal represetion
*/
static void _set_cca_thresh(uint8_t thresh)
{
NRF_RADIO->CCACTRL &= ~RADIO_CCACTRL_CCAEDTHRES_Msk;
NRF_RADIO->CCACTRL |= thresh << RADIO_CCACTRL_CCAEDTHRES_Pos;
}
/**
* @brief Check whether the channel is clear or not
* @note So far only CCA with Energy Detection is supported (CCA_MODE=1).
*/
static bool _channel_is_clear(void)
{
NRF_RADIO->CCACTRL |= RADIO_CCACTRL_CCAMODE_EdMode;
NRF_RADIO->EVENTS_CCAIDLE = 0;
NRF_RADIO->EVENTS_CCABUSY = 0;
NRF_RADIO->TASKS_CCASTART = 1;
for(;;) {
if(NRF_RADIO->EVENTS_CCAIDLE) {
return true;
}
if(NRF_RADIO->EVENTS_CCABUSY) {
return false;
}
}
}
/**
* @brief Reset the RXIDLE state
*/
@ -243,6 +301,9 @@ static int _init(netdev_t *dev)
/* set default channel */
_set_chan(nrf802154_dev.chan);
/* set default CCA threshold */
_set_cca_thresh(CONFIG_NRF802154_CCA_THRESH_DEFAULT);
/* configure some shortcuts */
NRF_RADIO->SHORTS = RADIO_SHORTS_RXREADY_START_Msk | RADIO_SHORTS_TXREADY_START_Msk;
@ -382,7 +443,14 @@ static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len)
assert(max_len >= sizeof(int16_t));
*((int16_t *)value) = _get_txpower();
return sizeof(int16_t);
case NETOPT_IS_CHANNEL_CLR:
assert(max_len >= sizeof(netopt_enable_t));
*((netopt_enable_t*)value) = _channel_is_clear();
return sizeof(netopt_enable_t);
case NETOPT_CCA_THRESHOLD:
assert(max_len >= sizeof(int8_t));
*((int8_t*)value) = _hwval_to_ieee802154_dbm(_get_cca_thresh());
return sizeof(netopt_enable_t);
default:
return netdev_ieee802154_get((netdev_ieee802154_t *)dev,
opt, value, max_len);
@ -400,6 +468,7 @@ static int _set(netdev_t *dev, netopt_t opt,
DEBUG("[nrf802154] set: %d\n", opt);
#endif
int8_t tmp;
switch (opt) {
case NETOPT_CHANNEL:
assert(value_len == sizeof(uint16_t));
@ -409,7 +478,15 @@ static int _set(netdev_t *dev, netopt_t opt,
assert(value_len == sizeof(int16_t));
_set_txpower(*((int16_t *)value));
return sizeof(int16_t);
case NETOPT_CCA_THRESHOLD:
assert(value_len == sizeof(int8_t));
tmp = *((int8_t*) value);
/* ED offset cannot be less than the min RSSI offset */
if ((tmp - ED_RSSIOFFS) < 0) {
return -EINVAL;
}
_set_cca_thresh(_dbm_to_ieee802154_hwval(tmp));
return sizeof(int8_t);
default:
return netdev_ieee802154_set((netdev_ieee802154_t *)dev,
opt, value, value_len);