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
17 changes: 13 additions & 4 deletions nimble/drivers/nrf5x/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ 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"
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