During the initial integration of controller to Zephyr OS, radio hardware access was abstracted out into hal/radio.c file. Bug introduced in hal/radio.c has been fixed so that whitelist feature works again. Change-id: Ie5faf80b1a008ef326613548a5a28a4ba52e7ef7 Signed-off-by: Vinayak Chettimada <vinayak.kariappa.chettimada@nordicsemi.no>
559 lines
13 KiB
C
559 lines
13 KiB
C
/*
|
|
* Copyright (c) 2016 Nordic Semiconductor ASA
|
|
* Copyright (c) 2016 Vinayak Kariappa Chettimada
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include <soc.h>
|
|
#include <misc/util.h>
|
|
|
|
#include "hal_work.h"
|
|
|
|
#include "defines.h"
|
|
#include "ccm.h"
|
|
#include "radio.h"
|
|
|
|
#if defined(CONFIG_SOC_SERIES_NRF51X)
|
|
#define RADIO_PDU_LEN_MAX (BIT(5) - 1)
|
|
#elif defined(NRF52)
|
|
#define RADIO_PDU_LEN_MAX (BIT(8) - 1)
|
|
#else
|
|
#error "Platform not defined."
|
|
#endif
|
|
|
|
static radio_isr_fp sfp_radio_isr;
|
|
|
|
void radio_isr(void)
|
|
{
|
|
if (sfp_radio_isr) {
|
|
sfp_radio_isr();
|
|
}
|
|
}
|
|
|
|
void radio_isr_set(radio_isr_fp fp_radio_isr)
|
|
{
|
|
sfp_radio_isr = fp_radio_isr; /* atomic assignment of 32-bit word */
|
|
|
|
NRF_RADIO->INTENSET = (0 |
|
|
/* RADIO_INTENSET_READY_Msk |
|
|
* RADIO_INTENSET_ADDRESS_Msk |
|
|
* RADIO_INTENSET_PAYLOAD_Msk |
|
|
* RADIO_INTENSET_END_Msk |
|
|
*/
|
|
RADIO_INTENSET_DISABLED_Msk
|
|
/* | RADIO_INTENSET_RSSIEND_Msk |
|
|
*/
|
|
);
|
|
|
|
_NvicIrqUnpend(RADIO_IRQn);
|
|
irq_enable(RADIO_IRQn);
|
|
}
|
|
|
|
void radio_reset(void)
|
|
{
|
|
irq_disable(RADIO_IRQn);
|
|
|
|
NRF_RADIO->POWER =
|
|
((RADIO_POWER_POWER_Disabled << RADIO_POWER_POWER_Pos) &
|
|
RADIO_POWER_POWER_Msk);
|
|
NRF_RADIO->POWER =
|
|
((RADIO_POWER_POWER_Enabled << RADIO_POWER_POWER_Pos) &
|
|
RADIO_POWER_POWER_Msk);
|
|
}
|
|
|
|
void radio_phy_set(uint8_t phy)
|
|
{
|
|
NRF_RADIO->MODE =
|
|
(((phy) ? (uint32_t)phy : RADIO_MODE_MODE_Ble_1Mbit) <<
|
|
RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk;
|
|
}
|
|
|
|
void radio_tx_power_set(uint32_t power)
|
|
{
|
|
/* TODO map power to h/w values. */
|
|
NRF_RADIO->TXPOWER = power;
|
|
}
|
|
|
|
void radio_freq_chnl_set(uint32_t chnl)
|
|
{
|
|
NRF_RADIO->FREQUENCY = chnl;
|
|
}
|
|
|
|
void radio_whiten_iv_set(uint32_t iv)
|
|
{
|
|
NRF_RADIO->DATAWHITEIV = iv;
|
|
}
|
|
|
|
void radio_aa_set(uint8_t *aa)
|
|
{
|
|
NRF_RADIO->TXADDRESS =
|
|
(((0UL) << RADIO_TXADDRESS_TXADDRESS_Pos) &
|
|
RADIO_TXADDRESS_TXADDRESS_Msk);
|
|
NRF_RADIO->RXADDRESSES =
|
|
((RADIO_RXADDRESSES_ADDR0_Enabled) << RADIO_RXADDRESSES_ADDR0_Pos);
|
|
NRF_RADIO->PREFIX0 = aa[3];
|
|
NRF_RADIO->BASE0 = (aa[2] << 24) | (aa[1] << 16) | (aa[0] << 8);
|
|
}
|
|
|
|
void radio_pkt_configure(uint8_t preamble16, uint8_t bits_len, uint8_t max_len)
|
|
{
|
|
#if defined(CONFIG_SOC_SERIES_NRF51X)
|
|
ARG_UNUSED(preamble16);
|
|
|
|
if (bits_len == 8) {
|
|
bits_len = 5;
|
|
}
|
|
#endif
|
|
|
|
NRF_RADIO->PCNF0 = ((((1UL) << RADIO_PCNF0_S0LEN_Pos) &
|
|
RADIO_PCNF0_S0LEN_Msk) |
|
|
((((uint32_t)bits_len) << RADIO_PCNF0_LFLEN_Pos) &
|
|
RADIO_PCNF0_LFLEN_Msk) |
|
|
#if !defined(CONFIG_SOC_SERIES_NRF51X)
|
|
(((RADIO_PCNF0_S1INCL_Include) <<
|
|
RADIO_PCNF0_S1INCL_Pos) &
|
|
RADIO_PCNF0_S1INCL_Msk) |
|
|
((((preamble16) ? RADIO_PCNF0_PLEN_16bit :
|
|
RADIO_PCNF0_PLEN_8bit) << RADIO_PCNF0_PLEN_Pos) &
|
|
RADIO_PCNF0_PLEN_Msk) |
|
|
#endif
|
|
((((uint32_t)8-bits_len) <<
|
|
RADIO_PCNF0_S1LEN_Pos) &
|
|
RADIO_PCNF0_S1LEN_Msk));
|
|
|
|
NRF_RADIO->PCNF1 = (((((uint32_t)max_len) << RADIO_PCNF1_MAXLEN_Pos) &
|
|
RADIO_PCNF1_MAXLEN_Msk) |
|
|
(((0UL) << RADIO_PCNF1_STATLEN_Pos) &
|
|
RADIO_PCNF1_STATLEN_Msk) |
|
|
(((3UL) << RADIO_PCNF1_BALEN_Pos) &
|
|
RADIO_PCNF1_BALEN_Msk) |
|
|
(((RADIO_PCNF1_ENDIAN_Little) <<
|
|
RADIO_PCNF1_ENDIAN_Pos) &
|
|
RADIO_PCNF1_ENDIAN_Msk) |
|
|
(((1UL) << RADIO_PCNF1_WHITEEN_Pos) &
|
|
RADIO_PCNF1_WHITEEN_Msk));
|
|
}
|
|
|
|
void radio_pkt_rx_set(void *rx_packet)
|
|
{
|
|
NRF_RADIO->PACKETPTR = (uint32_t)rx_packet;
|
|
}
|
|
|
|
void radio_pkt_tx_set(void *tx_packet)
|
|
{
|
|
NRF_RADIO->PACKETPTR = (uint32_t)tx_packet;
|
|
}
|
|
|
|
void radio_rx_enable(void)
|
|
{
|
|
NRF_RADIO->TASKS_RXEN = 1;
|
|
}
|
|
|
|
void radio_tx_enable(void)
|
|
{
|
|
NRF_RADIO->TASKS_TXEN = 1;
|
|
}
|
|
|
|
void radio_disable(void)
|
|
{
|
|
NRF_RADIO->SHORTS = 0;
|
|
NRF_RADIO->TASKS_DISABLE = 1;
|
|
}
|
|
|
|
void radio_status_reset(void)
|
|
{
|
|
NRF_RADIO->EVENTS_READY = 0;
|
|
NRF_RADIO->EVENTS_ADDRESS = 0;
|
|
NRF_RADIO->EVENTS_PAYLOAD = 0;
|
|
NRF_RADIO->EVENTS_END = 0;
|
|
NRF_RADIO->EVENTS_DISABLED = 0;
|
|
}
|
|
|
|
uint32_t radio_is_ready(void)
|
|
{
|
|
return NRF_RADIO->EVENTS_READY;
|
|
}
|
|
|
|
uint32_t radio_is_done(void)
|
|
{
|
|
return NRF_RADIO->EVENTS_END;
|
|
}
|
|
|
|
uint32_t radio_has_disabled(void)
|
|
{
|
|
return NRF_RADIO->EVENTS_DISABLED;
|
|
}
|
|
|
|
uint32_t radio_is_idle(void)
|
|
{
|
|
return (NRF_RADIO->STATE == 0);
|
|
}
|
|
|
|
void radio_crc_configure(uint32_t polynomial, uint32_t iv)
|
|
{
|
|
NRF_RADIO->CRCCNF =
|
|
(((RADIO_CRCCNF_SKIPADDR_Skip) << RADIO_CRCCNF_SKIPADDR_Pos) &
|
|
RADIO_CRCCNF_SKIPADDR_Msk) |
|
|
(((RADIO_CRCCNF_LEN_Three) << RADIO_CRCCNF_LEN_Pos) &
|
|
RADIO_CRCCNF_LEN_Msk);
|
|
NRF_RADIO->CRCPOLY = polynomial;
|
|
NRF_RADIO->CRCINIT = iv;
|
|
}
|
|
|
|
uint32_t radio_crc_is_valid(void)
|
|
{
|
|
return NRF_RADIO->CRCSTATUS;
|
|
}
|
|
|
|
static uint8_t ALIGNED(4) _pkt_empty[RADIO_EMPDU_SIZE_MAX];
|
|
static uint8_t ALIGNED(4) _pkt_scratch[
|
|
((RADIO_PDU_LEN_MAX + 3) > RADIO_ACPDU_SIZE_MAX) ?
|
|
(RADIO_PDU_LEN_MAX + 3) : RADIO_ACPDU_SIZE_MAX];
|
|
|
|
void *radio_pkt_empty_get(void)
|
|
{
|
|
return _pkt_empty;
|
|
}
|
|
|
|
void *radio_pkt_scratch_get(void)
|
|
{
|
|
return _pkt_scratch;
|
|
}
|
|
|
|
void radio_switch_complete_and_rx(void)
|
|
{
|
|
NRF_RADIO->SHORTS =
|
|
(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk |
|
|
RADIO_SHORTS_DISABLED_RXEN_Msk);
|
|
}
|
|
|
|
void radio_switch_complete_and_tx(void)
|
|
{
|
|
NRF_RADIO->SHORTS =
|
|
(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk |
|
|
RADIO_SHORTS_DISABLED_TXEN_Msk);
|
|
}
|
|
|
|
void radio_switch_complete_and_disable(void)
|
|
{
|
|
NRF_RADIO->SHORTS =
|
|
(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk);
|
|
}
|
|
|
|
void radio_rssi_measure(void)
|
|
{
|
|
NRF_RADIO->SHORTS |=
|
|
(RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
|
|
RADIO_SHORTS_DISABLED_RSSISTOP_Msk);
|
|
}
|
|
|
|
uint32_t radio_rssi_get(void)
|
|
{
|
|
return NRF_RADIO->RSSISAMPLE;
|
|
}
|
|
|
|
void radio_rssi_status_reset(void)
|
|
{
|
|
NRF_RADIO->EVENTS_RSSIEND = 0;
|
|
}
|
|
|
|
uint32_t radio_rssi_is_ready(void)
|
|
{
|
|
return NRF_RADIO->EVENTS_RSSIEND;
|
|
}
|
|
|
|
void radio_filter_configure(uint8_t bitmask_enable,
|
|
uint8_t bitmask_addr_type,
|
|
uint8_t *bdaddr)
|
|
{
|
|
uint8_t index;
|
|
|
|
for (index = 0; index < 8; index++) {
|
|
NRF_RADIO->DAB[index] = ((uint32_t)bdaddr[3] << 24) |
|
|
((uint32_t)bdaddr[2] << 16) |
|
|
((uint32_t)bdaddr[1] << 8) |
|
|
bdaddr[0];
|
|
NRF_RADIO->DAP[index] = ((uint32_t)bdaddr[5] << 8) | bdaddr[4];
|
|
bdaddr += BDADDR_SIZE;
|
|
}
|
|
|
|
NRF_RADIO->DACNF = ((uint32_t)bitmask_addr_type << 8) | bitmask_enable;
|
|
}
|
|
|
|
void radio_filter_disable(void)
|
|
{
|
|
NRF_RADIO->DACNF &= ~(0x000000FF);
|
|
}
|
|
|
|
void radio_filter_status_reset(void)
|
|
{
|
|
NRF_RADIO->EVENTS_DEVMATCH = 0;
|
|
NRF_RADIO->EVENTS_DEVMISS = 0;
|
|
}
|
|
|
|
uint32_t radio_filter_has_match(void)
|
|
{
|
|
return NRF_RADIO->EVENTS_DEVMATCH;
|
|
}
|
|
|
|
void radio_bc_configure(uint32_t n)
|
|
{
|
|
NRF_RADIO->BCC = n;
|
|
NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_BCSTART_Msk;
|
|
}
|
|
|
|
void radio_bc_status_reset(void)
|
|
{
|
|
NRF_RADIO->EVENTS_BCMATCH = 0;
|
|
}
|
|
|
|
uint32_t radio_bc_has_match(void)
|
|
{
|
|
return NRF_RADIO->EVENTS_BCMATCH;
|
|
}
|
|
|
|
void radio_tmr_status_reset(void)
|
|
{
|
|
NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk;
|
|
NRF_PPI->CHENCLR =
|
|
(PPI_CHEN_CH0_Msk | PPI_CHEN_CH1_Msk | PPI_CHEN_CH2_Msk |
|
|
PPI_CHEN_CH3_Msk | PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk |
|
|
PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk);
|
|
}
|
|
|
|
void radio_tmr_tifs_set(uint32_t tifs)
|
|
{
|
|
NRF_RADIO->TIFS = tifs;
|
|
}
|
|
|
|
uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
|
|
{
|
|
if ((!(remainder / 1000000UL)) || (remainder & 0x80000000)) {
|
|
ticks_start--;
|
|
remainder += 30517578UL;
|
|
}
|
|
remainder /= 1000000UL;
|
|
|
|
NRF_TIMER0->TASKS_CLEAR = 1;
|
|
NRF_TIMER0->MODE = 0;
|
|
NRF_TIMER0->PRESCALER = 4;
|
|
NRF_TIMER0->BITMODE = 2; /* 24 - bit */
|
|
|
|
NRF_TIMER0->CC[0] = remainder;
|
|
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
|
|
|
|
NRF_RTC0->CC[2] = ticks_start;
|
|
NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE2_Msk;
|
|
NRF_RTC0->EVENTS_COMPARE[2] = 0;
|
|
|
|
NRF_PPI->CH[1].EEP = (uint32_t)&(NRF_RTC0->EVENTS_COMPARE[2]);
|
|
NRF_PPI->CH[1].TEP = (uint32_t)&(NRF_TIMER0->TASKS_START);
|
|
NRF_PPI->CHENSET = PPI_CHEN_CH1_Msk;
|
|
|
|
if (trx) {
|
|
NRF_PPI->CH[0].EEP =
|
|
(uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
|
|
NRF_PPI->CH[0].TEP =
|
|
(uint32_t)&(NRF_RADIO->TASKS_TXEN);
|
|
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
|
|
} else {
|
|
NRF_PPI->CH[0].EEP =
|
|
(uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
|
|
NRF_PPI->CH[0].TEP =
|
|
(uint32_t)&(NRF_RADIO->TASKS_RXEN);
|
|
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
|
|
}
|
|
|
|
return remainder;
|
|
}
|
|
|
|
void radio_tmr_stop(void)
|
|
{
|
|
NRF_TIMER0->TASKS_STOP = 1;
|
|
NRF_TIMER0->TASKS_SHUTDOWN = 1;
|
|
}
|
|
|
|
void radio_tmr_hcto_configure(uint32_t hcto)
|
|
{
|
|
NRF_TIMER0->CC[2] = hcto;
|
|
NRF_TIMER0->EVENTS_COMPARE[2] = 0;
|
|
|
|
NRF_PPI->CH[4].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
|
|
NRF_PPI->CH[4].TEP = (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
|
|
NRF_PPI->CH[5].EEP = (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[2]);
|
|
NRF_PPI->CH[5].TEP = (uint32_t)&(NRF_RADIO->TASKS_DISABLE);
|
|
NRF_PPI->CHENSET = (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk);
|
|
}
|
|
|
|
void radio_tmr_aa_capture(void)
|
|
{
|
|
NRF_PPI->CH[2].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY);
|
|
NRF_PPI->CH[2].TEP = (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[0]);
|
|
NRF_PPI->CH[3].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
|
|
NRF_PPI->CH[3].TEP = (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[1]);
|
|
NRF_PPI->CHENSET = (PPI_CHEN_CH2_Msk | PPI_CHEN_CH3_Msk);
|
|
}
|
|
|
|
uint32_t radio_tmr_aa_get(void)
|
|
{
|
|
return (NRF_TIMER0->CC[1] - NRF_TIMER0->CC[0]);
|
|
}
|
|
|
|
void radio_tmr_end_capture(void)
|
|
{
|
|
NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_END);
|
|
NRF_PPI->CH[7].TEP = (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
|
|
NRF_PPI->CHENSET = PPI_CHEN_CH7_Msk;
|
|
}
|
|
|
|
uint32_t radio_tmr_end_get(void)
|
|
{
|
|
return NRF_TIMER0->CC[2];
|
|
}
|
|
|
|
static uint8_t ALIGNED(4) _ccm_scratch[(RADIO_PDU_LEN_MAX - 4) + 16];
|
|
|
|
void *radio_ccm_rx_pkt_set(struct ccm *ccm, void *pkt)
|
|
{
|
|
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
|
|
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
|
|
NRF_CCM->MODE =
|
|
#if !defined(CONFIG_SOC_SERIES_NRF51X)
|
|
((CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
|
|
CCM_MODE_LENGTH_Msk) |
|
|
#endif
|
|
((CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
|
|
CCM_MODE_MODE_Msk);
|
|
NRF_CCM->CNFPTR = (uint32_t)ccm;
|
|
NRF_CCM->INPTR = (uint32_t)_pkt_scratch;
|
|
NRF_CCM->OUTPTR = (uint32_t)pkt;
|
|
NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
|
|
NRF_CCM->SHORTS = 0;
|
|
NRF_CCM->EVENTS_ENDKSGEN = 0;
|
|
NRF_CCM->EVENTS_ENDCRYPT = 0;
|
|
NRF_CCM->EVENTS_ERROR = 0;
|
|
|
|
NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
|
|
NRF_PPI->CH[6].TEP = (uint32_t)&(NRF_CCM->TASKS_CRYPT);
|
|
NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk;
|
|
|
|
NRF_CCM->TASKS_KSGEN = 1;
|
|
|
|
return _pkt_scratch;
|
|
}
|
|
|
|
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt)
|
|
{
|
|
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
|
|
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
|
|
NRF_CCM->MODE =
|
|
#if !defined(CONFIG_SOC_SERIES_NRF51X)
|
|
((CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
|
|
CCM_MODE_LENGTH_Msk) |
|
|
#endif
|
|
((CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
|
|
CCM_MODE_MODE_Msk);
|
|
NRF_CCM->CNFPTR = (uint32_t)ccm;
|
|
NRF_CCM->INPTR = (uint32_t)pkt;
|
|
NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch;
|
|
NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
|
|
NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
|
|
NRF_CCM->EVENTS_ENDKSGEN = 0;
|
|
NRF_CCM->EVENTS_ENDCRYPT = 0;
|
|
NRF_CCM->EVENTS_ERROR = 0;
|
|
|
|
#if defined(CONFIG_SOC_SERIES_NRF51X)
|
|
/* set up PPI to enable CCM */
|
|
NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY);
|
|
NRF_PPI->CH[6].TEP = (uint32_t)&(NRF_CCM->TASKS_KSGEN);
|
|
NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk;
|
|
#elif 0
|
|
/* encrypt tx packet */
|
|
NRF_CCM->INTENSET = CCM_INTENSET_ENDCRYPT_Msk;
|
|
NRF_CCM->TASKS_KSGEN = 1;
|
|
while (NRF_CCM->EVENTS_ENDCRYPT == 0) {
|
|
__WFE();
|
|
__SEV();
|
|
__WFE();
|
|
}
|
|
NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk;
|
|
_NvicIrqUnpend(CCM_AAR_IRQn);
|
|
|
|
LL_ASSERT(NRF_CCM->EVENTS_ERROR == 0);
|
|
#else
|
|
/* start KSGEN early, but dont wait for ENDCRYPT */
|
|
NRF_CCM->TASKS_KSGEN = 1;
|
|
#endif
|
|
|
|
return _pkt_scratch;
|
|
}
|
|
|
|
uint32_t radio_ccm_is_done(void)
|
|
{
|
|
NRF_CCM->INTENSET = CCM_INTENSET_ENDCRYPT_Msk;
|
|
while (NRF_CCM->EVENTS_ENDCRYPT == 0) {
|
|
__WFE();
|
|
__SEV();
|
|
__WFE();
|
|
}
|
|
NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk;
|
|
_NvicIrqUnpend(CCM_AAR_IRQn);
|
|
|
|
return (NRF_CCM->EVENTS_ERROR == 0);
|
|
}
|
|
|
|
uint32_t radio_ccm_mic_is_valid(void)
|
|
{
|
|
return NRF_CCM->MICSTATUS;
|
|
}
|
|
|
|
static uint8_t ALIGNED(4) _aar_scratch[3];
|
|
|
|
void radio_ar_configure(uint32_t nirk, void *irk)
|
|
{
|
|
NRF_AAR->ENABLE = 1;
|
|
NRF_AAR->NIRK = nirk;
|
|
NRF_AAR->IRKPTR = (uint32_t)irk;
|
|
NRF_AAR->ADDRPTR = (uint32_t)NRF_RADIO->PACKETPTR;
|
|
NRF_AAR->SCRATCHPTR = (uint32_t)_aar_scratch[0];
|
|
|
|
radio_bc_configure(64);
|
|
|
|
NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_BCMATCH);
|
|
NRF_PPI->CH[6].TEP = (uint32_t)&(NRF_AAR->TASKS_START);
|
|
NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk;
|
|
}
|
|
|
|
uint32_t radio_ar_match_get(void)
|
|
{
|
|
return NRF_AAR->STATUS;
|
|
}
|
|
|
|
void radio_ar_status_reset(void)
|
|
{
|
|
if (radio_bc_has_match()) {
|
|
NRF_AAR->EVENTS_END = 0;
|
|
NRF_AAR->EVENTS_RESOLVED = 0;
|
|
NRF_AAR->EVENTS_NOTRESOLVED = 0;
|
|
}
|
|
|
|
radio_bc_status_reset();
|
|
}
|
|
|
|
uint32_t radio_ar_has_match(void)
|
|
{
|
|
return (radio_bc_has_match() &&
|
|
(NRF_AAR->EVENTS_END) &&
|
|
(NRF_AAR->EVENTS_RESOLVED));
|
|
}
|