Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions nimble/controller/include/controller/ble_phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,60 @@ struct os_mbuf;
/* Maximun PDU length. Includes LL header of 2 bytes and 255 bytes payload. */
#define BLE_PHY_MAX_PDU_LEN (257)

#if MYNEWT_VAL(BLE_LL_CHANNEL_SOUNDING)
#define BLE_PHY_CS_TRANSM_MODE_SYNC (0)
#define BLE_PHY_CS_TRANSM_MODE_TONE (1)

#define BLE_PHY_CS_TONE_MODE_PM (0)
#define BLE_PHY_CS_TONE_MODE_FM (1)

#define BLE_PHY_CS_STATUS_CONTINUE (0)
#define BLE_PHY_CS_STATUS_COMPLETE (1)
#define BLE_PHY_CS_STATUS_SYNC_LOST (2)

struct ble_phy_cs_transmission {
struct ble_phy_cs_transmission *next;
uint8_t *rtt_sequence;
uint32_t duration_usecs;
uint32_t aa;
uint16_t end_tifs;
uint8_t channel;
uint8_t mode;
uint8_t is_tx;
uint8_t tone_mode;
uint8_t rtt_sequence_len;
};

struct ble_phy_cs_sync_results {
uint32_t time_of_arrival_ns;
uint32_t time_of_departure_ns;
int16_t rssi;
};

struct ble_phy_cs_tone_results {
int16_t measured_freq_offset;
int16_t I16;
int16_t Q16;
uint16_t PHASE;
};

struct ble_phy_cs_subevent_results {
uint8_t status;
};

#if MYNEWT_VAL(BLE_PHY_CHANNEL_SOUNDING)
/* Configure the PHY for CS subevent sequence */
int ble_phy_cs_subevent_start(struct ble_phy_cs_transmission *transm, uint32_t cputime,
uint8_t rem_usecs, uint8_t phy_mode);
#else
static inline int ble_phy_cs_subevent_start(struct ble_phy_cs_transmission *transm, uint32_t cputime,
uint8_t rem_usecs, uint8_t phy_mode)
{
return 0;
}
#endif
#endif

/* Wait for response timer */
typedef void (*ble_phy_tx_end_func)(void *arg);

Expand Down
23 changes: 19 additions & 4 deletions nimble/drivers/nrf5x/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,22 @@ pkg.deps:
- nimble
- nimble/controller

pkg.ign_dirs.'MCU_TARGET=="nRF5340_NET"':
- nrf52
pkg.ign_dirs.'MCU_TARGET!="nRF5340_NET"':
- nrf53
pkg.source_files:
- "src/ble_hw.c"
- "src/ble_phy.c"
- "src/ble_phy_trace.c"

pkg.source_files.'MCU_TARGET=="nRF52810" || MCU_TARGET=="nRF52811" || MCU_TARGET=="nRF52832" || MCU_TARGET=="nRF52840"':
- "src/nrf52/phy.c"

pkg.source_files.'MCU_TARGET=="nRF5340_NET"':
- "src/nrf53/phy.c"

pkg.source_files.'MCU_TARGET=="nRF54L15"':
- "src/nrf54l/phy.c"

pkg.source_files.'BLE_CHANNEL_SOUNDING':
- "src/ble_phy_cs.c"

pkg.init.'BLE_PHY_CS_TEST_MODE_CONTINUES_TONE':
ble_phy_cs_tx_continuous_tone: $after:ble_transport_ll_init
137 changes: 134 additions & 3 deletions nimble/drivers/nrf5x/src/ble_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,25 @@
#include <nimble/nimble_npl_os.h>
#endif
#include "os/os_trace_api.h"
#ifndef NRF54L_SERIES
#include <hal/nrf_rng.h>
#endif
#include "hal/nrf_ecb.h"

#ifdef NRF54L_SERIES
#include <hal/nrf_cracen.h>

#define NRF_ECB NRF_ECB00
#define NRF_AAR NRF_AAR00

struct nrf_ecb_job_list {
nrf_vdma_job_t in[2];
nrf_vdma_job_t out[2];
};

static struct nrf_ecb_job_list g_ecb_job_list;
#endif

/* Total number of resolving list elements */
#define BLE_HW_RESOLV_LIST_SIZE (16)

Expand Down Expand Up @@ -276,6 +292,47 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb)
uint32_t end;
uint32_t err;

#ifdef NRF54L_SERIES
/* Stop ECB */
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOP);

/* Init job lists */
g_ecb_job_list.in[0].p_buffer = ecb->plain_text;
g_ecb_job_list.in[0].attributes = NRF_VDMA_ATTRIBUTE_CRC;
g_ecb_job_list.in[0].size = BLE_ENC_BLOCK_SIZE;
memset(&g_ecb_job_list.in[1], 0, sizeof(g_ecb_job_list.in[1]));

g_ecb_job_list.out[0].p_buffer = ecb->cipher_text;
g_ecb_job_list.out[0].attributes = NRF_VDMA_ATTRIBUTE_CRC;
g_ecb_job_list.out[0].size = BLE_ENC_BLOCK_SIZE;
memset(&g_ecb_job_list.out[1], 0, sizeof(g_ecb_job_list.out[1]));

NRF_ECB->KEY.VALUE[3] = get_be32(&ecb->key[0]);
NRF_ECB->KEY.VALUE[2] = get_be32(&ecb->key[4]);
NRF_ECB->KEY.VALUE[1] = get_be32(&ecb->key[8]);
NRF_ECB->KEY.VALUE[0] = get_be32(&ecb->key[12]);

NRF_ECB->EVENTS_END = 0;
NRF_ECB->EVENTS_ERROR = 0;
NRF_ECB->IN.PTR = (uint32_t)g_ecb_job_list.in;
NRF_ECB->OUT.PTR = (uint32_t)g_ecb_job_list.out;

/* Start ECB */
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_START);

/* Wait till error or done */
rc = 0;
while (1) {
end = NRF_ECB->EVENTS_END;
err = NRF_ECB->EVENTS_ERROR;
if (end || err) {
if (err) {
rc = -1;
}
break;
}
}
#else
/* Stop ECB */
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB);
/* XXX: does task stop clear these counters? Anyway to do this quicker? */
Expand All @@ -301,7 +358,7 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb)
tm_tick();
#endif
}

#endif
return rc;
}

Expand All @@ -314,7 +371,27 @@ ble_rng_isr(void)
uint8_t rnum;

os_trace_isr_enter();
#ifdef NRF54L_SERIES
(void)rnum;

/* No callback? Clear and disable interrupts */
if (g_ble_rng_isr_cb == NULL) {
nrf_cracen_int_disable(NRF_CRACEN, NRF_CRACEN_INT_RNG_MASK);
NRF_CRACENCORE->RNGCONTROL.CONTROL &= ~CRACENCORE_RNGCONTROL_CONTROL_INTENFULL_Msk;
NRF_CRACEN->EVENTS_RNG = 0;
os_trace_isr_exit();
return;
}

if (g_ble_rng_isr_cb) {
/* If there is a value ready in the queue grab it */
while ((NRF_CRACENCORE->RNGCONTROL.CONTROL &
CRACENCORE_RNGCONTROL_CONTROL_INTENFULL_Msk) &&
(NRF_CRACENCORE->RNGCONTROL.FIFOLEVEL > 0)) {
g_ble_rng_isr_cb(ble_hw_rng_read());
}
}
#else
/* No callback? Clear and disable interrupts */
if (g_ble_rng_isr_cb == NULL) {
nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK);
Expand All @@ -330,7 +407,7 @@ ble_rng_isr(void)
rnum = (uint8_t)NRF_RNG->VALUE;
(*g_ble_rng_isr_cb)(rnum);
}

#endif
os_trace_isr_exit();
}

Expand All @@ -345,6 +422,24 @@ ble_rng_isr(void)
int
ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
{
#ifdef NRF54L_SERIES
NRF_CRACEN->ENABLE = CRACEN_ENABLE_CRYPTOMASTER_Msk |
CRACEN_ENABLE_RNG_Msk |
CRACEN_ENABLE_PKEIKG_Msk;

while (NRF_CRACENCORE->PK.STATUS & CRACENCORE_PK_STATUS_PKBUSY_Msk);
NRF_CRACENCORE->PK.CONTROL &= ~CRACENCORE_IKG_PKECONTROL_CLEARIRQ_Msk;

NRF_CRACENCORE->RNGCONTROL.CONTROL = CRACENCORE_RNGCONTROL_CONTROL_ResetValue |
CRACENCORE_RNGCONTROL_CONTROL_ENABLE_Msk;

/* If we were passed a function pointer we need to enable the interrupt */
if (cb != NULL) {
NVIC_SetVector(CRACEN_IRQn, (uint32_t)ble_rng_isr);
NVIC_EnableIRQ(CRACEN_IRQn);
g_ble_rng_isr_cb = cb;
}
#else
/* Set bias */
if (bias) {
NRF_RNG->CONFIG = 1;
Expand All @@ -365,6 +460,7 @@ ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
NVIC_EnableIRQ(RNG_IRQn);
g_ble_rng_isr_cb = cb;
}
#endif

return 0;
}
Expand All @@ -381,12 +477,23 @@ ble_hw_rng_start(void)

/* No need for interrupt if there is no callback */
OS_ENTER_CRITICAL(sr);
#ifdef NRF54L_SERIES
NRF_CRACEN->EVENTS_RNG = 0;

if (g_ble_rng_isr_cb) {
nrf_cracen_int_enable(NRF_CRACEN, NRF_CRACEN_INT_RNG_MASK);
NRF_CRACENCORE->RNGCONTROL.CONTROL |= CRACENCORE_RNGCONTROL_CONTROL_INTENFULL_Msk;
/* Force regeneration of the samples */
NRF_CRACENCORE->RNGCONTROL.FIFOLEVEL = 0;
}
#else
NRF_RNG->EVENTS_VALRDY = 0;

if (g_ble_rng_isr_cb) {
nrf_rng_int_enable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK);
}
nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_START);
#endif
OS_EXIT_CRITICAL(sr);

return 0;
Expand All @@ -404,9 +511,15 @@ ble_hw_rng_stop(void)

/* No need for interrupt if there is no callback */
OS_ENTER_CRITICAL(sr);
#ifdef NRF54L_SERIES
nrf_cracen_int_disable(NRF_CRACEN, NRF_CRACEN_INT_RNG_MASK);
NRF_CRACENCORE->RNGCONTROL.CONTROL &= ~CRACENCORE_RNGCONTROL_CONTROL_INTENFULL_Msk;
NRF_CRACEN->EVENTS_RNG = 0;
#else
nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK);
nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP);
NRF_RNG->EVENTS_VALRDY = 0;
#endif
OS_EXIT_CRITICAL(sr);

return 0;
Expand All @@ -421,14 +534,28 @@ uint8_t
ble_hw_rng_read(void)
{
uint8_t rnum;
#ifdef NRF54L_SERIES
uint8_t slot_id;

/* Wait for a sample */
while (NRF_CRACENCORE->RNGCONTROL.FIFOLEVEL == 0) {
assert((NRF_CRACENCORE->RNGCONTROL.STATUS &
CRACENCORE_RNGCONTROL_STATUS_STATE_Msk) !=
(CRACENCORE_RNGCONTROL_STATUS_STATE_ERROR <<
CRACENCORE_RNGCONTROL_STATUS_STATE_Pos));
}

NRF_CRACEN->EVENTS_RNG = 0;
slot_id = NRF_CRACENCORE->RNGCONTROL.FIFODEPTH - NRF_CRACENCORE->RNGCONTROL.FIFOLEVEL;
rnum = (uint8_t)NRF_CRACENCORE->RNGCONTROL.FIFO[slot_id];
#else
/* Wait for a sample */
while (NRF_RNG->EVENTS_VALRDY == 0) {
}

NRF_RNG->EVENTS_VALRDY = 0;
rnum = (uint8_t)NRF_RNG->VALUE;

#endif
return rnum;
}

Expand Down Expand Up @@ -511,7 +638,11 @@ int
ble_hw_resolv_list_match(void)
{
if (NRF_AAR->ENABLE && NRF_AAR->EVENTS_END && NRF_AAR->EVENTS_RESOLVED) {
#ifdef NRF54L_SERIES
return (int)NRF_AAR->ERRORSTATUS;
#else
return (int)NRF_AAR->STATUS;
#endif
}

return -1;
Expand Down
Loading
Loading