Dear experts,
I am programming bare metal using Segger Embedded Studio and nrf.h and want to achieve a simple example of network core sending data to the application core.
Since the network core runs in non-secure domain and application core runs in secure domain, there is a bit of initialization needed but I cannot get it to work.
Here is my example:
In main() on the application core, I run
spu_configure(); ipc_rx_configure(); ipc_rx_recieve();
spu:
#include "SPU.h"
// IPC is peripheral ID 42 on nRF5340
#define IPC_PERIPH_ID 42
void spu_configure(void) {
// In secure boot eller startup på application core
// Configure RAM region 63 (0x2003E000-0x2003FFF) as non-secure
NRF_SPU_S->RAMREGION[63].PERM =
(SPU_RAMREGION_PERM_READ_Msk |
SPU_RAMREGION_PERM_WRITE_Msk |
SPU_RAMREGION_PERM_EXECUTE_Msk); // SECATTR bit is 0 => non-secure
NRF_SPU_S->PERIPHID[IPC_PERIPH_ID].PERM &= ~SPU_PERIPHID_PERM_SECATTR_NonSecure;
// SECATTR = 0 => non-secure access
}and ipc_rx
#include "ipc_rx.h"
#define SHARED_MEM_ADDR ((volatile uint8_t*)0x2003E000)
typedef struct {
uint8_t id;
uint16_t value;
char label[8];
} message_t;
// Configure the app core to trigger an event every time a message is transmitted from network core
void ipc_rx_configure(void) {
// Enable interrupt for RECEIVE[0]
NRF_IPC_S->INTENSET = IPC_INTENSET_RECEIVE0_Msk;
NVIC_EnableIRQ(IPC_IRQn);
}
void ipc_rx_recieve(void) {
// From now on this will be interrupt driven so stay here
while (1) {
__WFE();
}
}
// This event will be triggered every time there is a message.
void IPC_IRQHandler(void) {
if (NRF_IPC_S->EVENTS_RECEIVE[0]) {
NRF_IPC_S->EVENTS_RECEIVE[0] = 0;
message_t *msg = (message_t *)SHARED_MEM_ADDR;
printf("Message: ");
printf("%s", msg->label);
printf(" \n");
// Use msg->id, msg->value, msg->label
}
}
In network core I run<
main()
ipc_tx_configure();
for (int i=1; i<1000; i++) {
ipc_tx_transmit();
for(int j=0; j<50000; j++) {
float dummy = sinf(sinf(3.56));
}
}and ipc_tx
#include "ipc_tx.h"
#define SHARED_MEM_ADDR ((volatile uint8_t*)0x2003E000)
typedef struct {
uint8_t id;
uint16_t value;
char label[8];
} message_t;
void ipc_tx_configure(void){
// Not really needed
}
void ipc_tx_transmit(void) {
message_t *msg = (message_t *)SHARED_MEM_ADDR;
msg->id = 1;
msg->value = 1234;
memcpy(msg->label, "TEMP", 5);
// Trigger IPC event on channel 0
NRF_IPC_NS->TASKS_SEND[0] = 1;
}The code compiles and runs but I cannot seem to get the interrupt triggered on the application core
Any help appreciated.
/Jonas