Contiki-NG
Loading...
Searching...
No Matches
nrf-ipc-mac.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 * \file
33 * IPC MAC driver for the nRF5340 network core.
34 *
35 * This MAC driver runs on the network core and forwards received
36 * frames to the application core via the IPC shared memory. It
37 * replaces NULLMAC for the net core, enabling fully interrupt-driven
38 * frame reception: the radio ISR triggers the radio driver process,
39 * which reads the frame and calls this MAC's input function.
40 *
41 * \author
42 * Nicolas Tsiftes <nicolas.tsiftes@ri.se>
43 */
44/*---------------------------------------------------------------------------*/
45#include "contiki.h"
46#include "net/mac/mac.h"
47#include "net/netstack.h"
48#include "net/packetbuf.h"
49#include "nrf-ipc.h"
50
51#include <inttypes.h>
52#include <string.h>
53/*---------------------------------------------------------------------------*/
54#include "sys/log.h"
55#define LOG_MODULE "IPC MAC"
56#define LOG_LEVEL LOG_LEVEL_INFO
57/*---------------------------------------------------------------------------*/
58static volatile struct nrf_ipc_shared_mem *shm = NRF_IPC_SHARED_MEM;
59/*---------------------------------------------------------------------------*/
60static uint32_t rx_drop_count;
61/*---------------------------------------------------------------------------*/
62/**
63 * 802.15.4 ACK frame constants.
64 */
65#define ACK_FRAME_LEN 3
66#define FCF_ACK_REQUEST_BIT 0x20
67#define FRAME802154_ACKFRAME 0x02
68/*---------------------------------------------------------------------------*/
69/*
70 * Whether the underlying net-core radio acknowledges received frames in
71 * hardware. The nrf_802154 driver does (nrf_802154_auto_ack_set), so the
72 * software ACK below must be disabled to avoid a double ACK. The raw
73 * nrf-ieee-driver-arch.c does not, so it stays enabled by default.
74 */
75#ifdef NRF_IPC_MAC_CONF_HW_AUTOACK
76#define NRF_IPC_MAC_HW_AUTOACK NRF_IPC_MAC_CONF_HW_AUTOACK
77#else
78#define NRF_IPC_MAC_HW_AUTOACK 0
79#endif
80/*---------------------------------------------------------------------------*/
81#if !NRF_IPC_MAC_HW_AUTOACK
82/**
83 * Send a software ACK for a received frame if the ACK request bit is set.
84 */
85static void
86send_ack_if_needed(const uint8_t *frame, int len)
87{
88 uint8_t ack[ACK_FRAME_LEN];
89 radio_value_t tx_mode;
90
91 if(len < ACK_FRAME_LEN) {
92 return;
93 }
94
95 /*
96 * The net core's nRF radio has no hardware auto-ACK and does not
97 * report RADIO_RX_MODE_AUTOACK via get_value(), so the IPC MAC must
98 * generate the link-layer ACK in software for every unicast frame
99 * that requests one (checked below via the ACK request bit). The
100 * app core's CSMA relies on these ACKs to confirm its transmissions.
101 */
102
103 /* Do not ACK frames that are themselves ACKs. */
104 if((frame[0] & 0x07) == FRAME802154_ACKFRAME) {
105 return;
106 }
107
108 /* Check the ACK request bit (bit 5 of FCF byte 0). */
109 if(!(frame[0] & FCF_ACK_REQUEST_BIT)) {
110 return;
111 }
112
113 /* Build ACK: [Frame Control = ACK type, 0x00, Sequence Number]. */
114 ack[0] = FRAME802154_ACKFRAME;
115 ack[1] = 0;
116 ack[2] = frame[2]; /* DSN is byte 2 of the received frame. */
117
118 /*
119 * 802.15.4 requires ACKs to be sent without CCA. Clear only the
120 * SEND_ON_CCA bit and restore the previous TX mode afterwards, so
121 * any other (current or future) TX mode flags are preserved.
122 */
123 if(NETSTACK_RADIO.get_value(RADIO_PARAM_TX_MODE, &tx_mode) != RADIO_RESULT_OK) {
125 }
126 NETSTACK_RADIO.set_value(RADIO_PARAM_TX_MODE,
127 tx_mode & ~RADIO_TX_MODE_SEND_ON_CCA);
128 NETSTACK_RADIO.send(ack, ACK_FRAME_LEN);
129 NETSTACK_RADIO.set_value(RADIO_PARAM_TX_MODE, tx_mode);
130}
131#endif /* !NRF_IPC_MAC_HW_AUTOACK */
132/*---------------------------------------------------------------------------*/
133static void
134init(void)
135{
136}
137/*---------------------------------------------------------------------------*/
138static void
139send_packet(mac_callback_t sent, void *ptr)
140{
141}
142/*---------------------------------------------------------------------------*/
143/**
144 * Called by the radio driver process when a frame has been received.
145 * The frame is in packetbuf. We send a software ACK, then forward the
146 * raw frame to the application core via shared memory.
147 */
148static void
150{
151 const uint8_t *frame;
152 int len;
153
154 frame = packetbuf_dataptr();
155 len = packetbuf_datalen();
156
157 /* Use heartbeat field as RX frame counter (readable via debugger). */
158 shm->heartbeat++;
159
160 if(len <= 0 || len > NRF_IPC_MAX_FRAME_LEN) {
161 return;
162 }
163
164 /*
165 * Sort incoming frames into ACK vs data paths. ACK frames (3 bytes,
166 * frame type 0x02) go to shm->rx_ack for CSMA's tight ACK detection
167 * loop. All other frames go to shm->rx for delivery via the process
168 * thread. This separation prevents CSMA's RTIMER_BUSYWAIT from
169 * consuming and discarding data frames while checking for ACKs.
170 */
171 if(len == ACK_FRAME_LEN && (frame[0] & 0x07) == FRAME802154_ACKFRAME) {
172 /* ACK frame — goes to the dedicated ACK slot. */
173 if(!shm->rx_ack.pending) {
174 memcpy((void *)shm->rx_ack.data, frame, ACK_FRAME_LEN);
175 __DMB();
176 shm->rx_ack.pending = 1;
177 }
179 return;
180 }
181
182#if !NRF_IPC_MAC_HW_AUTOACK
183 /* Send a software ACK for non-ACK frames, before forwarding. The radio
184 * does this in hardware when nrf_802154 is used (see NRF_IPC_MAC_HW_AUTOACK). */
185 send_ack_if_needed(frame, len);
186#endif
187
188 /* Data frame — goes to the main RX slot. */
189 if(shm->rx.pending) {
190 rx_drop_count++;
191 if((rx_drop_count % 100) == 1) {
192 LOG_WARN("RX drop (app core busy), total drops: %" PRIu32 "\n",
193 rx_drop_count);
194 }
195 return;
196 }
197
198 shm->rx.len = len;
199 memcpy((void *)shm->rx.data, frame, len);
200 shm->rx.rssi = (int8_t)packetbuf_attr(PACKETBUF_ATTR_RSSI);
201 shm->rx.lqi = (uint8_t)packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY);
202
203 __DMB();
204
205 shm->rx.pending = 1;
206
208}
209/*---------------------------------------------------------------------------*/
210static int
211on(void)
212{
213 return NETSTACK_RADIO.on();
214}
215/*---------------------------------------------------------------------------*/
216static int
217off(void)
218{
219 return NETSTACK_RADIO.off();
220}
221/*---------------------------------------------------------------------------*/
222static int
223max_payload(void)
224{
226}
227/*---------------------------------------------------------------------------*/
228const struct mac_driver ipc_mac_driver = {
229 "ipc-mac",
230 init,
231 send_packet,
233 on,
234 off,
235 max_payload,
236};
237/*---------------------------------------------------------------------------*/
static int off(void)
Definition cc2538-rf.c:533
static int on(void)
Definition cc2538-rf.c:517
static int init(void)
Definition cc2538-rf.c:556
#define NRF_IPC_MAX_FRAME_LEN
Maximum 802.15.4 frame size carried over IPC.
Definition nrf-ipc.h:75
void nrf_ipc_signal(void)
Send an IPC signal to the other core.
#define NRF_IPC_SHARED_MEM
Get a pointer to the shared memory structure.
Definition nrf-ipc.h:212
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition packetbuf.c:143
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition packetbuf.c:155
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
Definition radio.h:474
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio.
Definition radio.h:88
@ RADIO_RESULT_OK
The parameter was set/read successfully.
Definition radio.h:480
@ RADIO_PARAM_TX_MODE
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
Definition radio.h:180
static void send_packet(void)
This function is called by the 6lowpan code to send out a packet.
Header file for the logging system.
MAC driver header file.
Include file for the Contiki low-layer network stack (NETSTACK).
#define ACK_FRAME_LEN
802.15.4 ACK frame constants.
Definition nrf-ipc-mac.c:65
static void packet_input(void)
Called by the radio driver process when a frame has been received.
static void send_ack_if_needed(const uint8_t *frame, int len)
Send a software ACK for a received frame if the ACK request bit is set.
Definition nrf-ipc-mac.c:86
IPC protocol definitions for nRF5340 dual-core communication.
Header file for the Packet buffer (packetbuf) management.
The structure of a MAC protocol driver in Contiki.
Definition mac.h:68
Shared memory layout between the application core and the network core.
Definition nrf-ipc.h:154