Contiki-NG
Loading...
Searching...
No Matches
nrf-ipc.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2026, RISE Research Institutes of Sweden AB.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/*---------------------------------------------------------------------------*/
31/**
32 * \addtogroup nrf-ipc
33 * @{
34 *
35 * \file
36 * IPC transport layer for nRF5340 inter-core communication
37 * \author
38 * Nicolas Tsiftes <nicolas.tsiftes@ri.se>
39 */
40/*---------------------------------------------------------------------------*/
41#include "contiki.h"
42#include "nrf-ipc.h"
43#include "nrf.h"
44#include "nrfx_config.h"
45/*---------------------------------------------------------------------------*/
46/* Only compile on nRF5340 platforms that have the IPC peripheral. */
47#ifdef NRF_IPC
48/*---------------------------------------------------------------------------*/
49#include "hal/nrf_ipc.h"
50/*---------------------------------------------------------------------------*/
51#include "sys/log.h"
52#define LOG_MODULE "IPC"
53#define LOG_LEVEL LOG_LEVEL_DBG
54/*---------------------------------------------------------------------------*/
55/*
56 * IPC channel assignments:
57 * - Channel 0: app core -> net core
58 * - Channel 1: net core -> app core
59 *
60 * Both cores use TASKS_SEND[0] to send and EVENTS_RECEIVE[0] to receive,
61 * but on different physical channels.
62 */
63#define IPC_APP_TO_NET_CHANNEL 0
64#define IPC_NET_TO_APP_CHANNEL 1
65/*---------------------------------------------------------------------------*/
66static struct process *ipc_process;
67/*---------------------------------------------------------------------------*/
68/**
69 * \brief Initialize the IPC transport layer.
70 *
71 * Configures IPC send/receive channels based on which core is
72 * running, enables the receive interrupt, and registers a process
73 * to poll when an IPC signal arrives from the other core.
74 *
75 * Channel assignment:
76 * - Channel 0: app core -> net core
77 * - Channel 1: net core -> app core
78 *
79 * \param callback_proc Process to poll on IPC receive, or NULL.
80 */
81void
82nrf_ipc_init(struct process *callback_proc)
83{
84 ipc_process = callback_proc;
85
86#if defined(NRF5340_XXAA_APPLICATION)
87 /*
88 * App core sends on channel 0, receives on channel 1.
89 * SEND_CNF[0]: TASKS_SEND[0] triggers channel 0
90 * RECEIVE_CNF[0]: channel 1 triggers EVENTS_RECEIVE[0]
91 */
92 nrf_ipc_send_config_set(NRF_IPC, 0,
93 (1UL << IPC_APP_TO_NET_CHANNEL));
94 nrf_ipc_receive_config_set(NRF_IPC, 0,
95 (1UL << IPC_NET_TO_APP_CHANNEL));
96#elif defined(NRF5340_XXAA_NETWORK)
97 /*
98 * Net core sends on channel 1, receives on channel 0.
99 * SEND_CNF[0]: TASKS_SEND[0] triggers channel 1
100 * RECEIVE_CNF[0]: channel 0 triggers EVENTS_RECEIVE[0]
101 */
102 nrf_ipc_send_config_set(NRF_IPC, 0,
103 (1UL << IPC_NET_TO_APP_CHANNEL));
104 nrf_ipc_receive_config_set(NRF_IPC, 0,
105 (1UL << IPC_APP_TO_NET_CHANNEL));
106#endif
107
108 /* Clear any pending events and enable the receive interrupt. */
109 nrf_ipc_event_clear(NRF_IPC, nrf_ipc_receive_event_get(0));
110 nrf_ipc_int_enable(NRF_IPC, (1UL << 0));
111
112 NVIC_ClearPendingIRQ(IPC_IRQn);
113 NVIC_EnableIRQ(IPC_IRQn);
114
115 LOG_DBG("IPC initialized\n");
116}
117/*---------------------------------------------------------------------------*/
118/**
119 * \brief Send an IPC signal to the other core.
120 *
121 * Triggers TASKS_SEND[0], which maps to the appropriate physical
122 * IPC channel based on the configuration set by nrf_ipc_init().
123 */
124void
125nrf_ipc_signal(void)
126{
127 nrf_ipc_task_trigger(NRF_IPC, nrf_ipc_send_task_get(0));
128}
129/*---------------------------------------------------------------------------*/
130/**
131 * \brief IPC interrupt handler.
132 *
133 * Called when the other core triggers an IPC signal on our receive
134 * channel. Clears the event and polls the registered process.
135 */
136void
137IPC_IRQHandler(void)
138{
139 if(nrf_ipc_event_check(NRF_IPC, nrf_ipc_receive_event_get(0))) {
140 nrf_ipc_event_clear(NRF_IPC, nrf_ipc_receive_event_get(0));
141
142 if(ipc_process != NULL) {
143 process_poll(ipc_process);
144 }
145 /* In TrustZone mode, the secure world's ipc_radio_process will
146 * run when the normal world calls tz_api_poll(). RX frame
147 * delivery is handled via the tz_radio_notify_rx callback. */
148 }
149}
150/*---------------------------------------------------------------------------*/
151#endif /* NRF_IPC */
152/*---------------------------------------------------------------------------*/
153/**
154 * @}
155 */
void nrf_ipc_init(struct process *callback_proc)
Initialize the IPC transport layer.
void nrf_ipc_signal(void)
Send an IPC signal to the other core.
void process_poll(struct process *p)
Request a process to be polled.
Definition process.c:366
Header file for the logging system.
IPC protocol definitions for nRF5340 dual-core communication.