Contiki-NG
Loading...
Searching...
No Matches
board-rf-switch.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 * Author: Joakim Eriksson <joakim.eriksson@ri.se>
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10/**
11 * \file
12 * RF switch initialization for the Seeed XIAO nRF54L15.
13 */
14
15#include "contiki.h"
16#include BOARD_DEF_PATH
17
18#include "nrf_gpio.h"
19#include <string.h>
20#if BUILD_WITH_SHELL
21#include "shell.h"
22#include "shell-commands.h"
23#include "sys/etimer.h"
24#endif
25
26static bool rf_sw_external;
27static bool rf_sw_power_on = true;
28
29static void rf_switch_apply(void);
30
31#if BUILD_WITH_SHELL
32static void rf_switch_print_status(shell_output_func output);
33static PT_THREAD(cmd_rf_switch(struct pt *pt, shell_output_func output, char *args));
34PROCESS(xiao_nrf54l15_rf_switch_shell_process, "XIAO RF switch shell");
35
36static const struct shell_command_t rf_switch_commands[] = {
37 {
38 "rf-sw",
39 cmd_rf_switch,
40 "'> rf-sw': status | ceramic | external | power [0|1|off|on]"
41 },
42 { NULL, NULL, NULL }
43};
44
45static struct shell_command_set_t rf_switch_shell_set = {
46 .next = NULL,
47 .commands = rf_switch_commands,
48};
49#endif
50/*---------------------------------------------------------------------------*/
51static void
52rf_switch_apply(void)
53{
54 uint32_t rf_sw_sel =
55 NRF_GPIO_PIN_MAP(XIAO_NRF54L15_RF_SW_SEL_PORT, XIAO_NRF54L15_RF_SW_SEL_PIN);
56 uint32_t rf_sw_pwr =
57 NRF_GPIO_PIN_MAP(XIAO_NRF54L15_RF_SW_PWR_PORT, XIAO_NRF54L15_RF_SW_PWR_PIN);
58
59 nrf_gpio_cfg_output(rf_sw_sel);
60 nrf_gpio_cfg_output(rf_sw_pwr);
61
62 if(rf_sw_external) {
63 nrf_gpio_pin_set(rf_sw_sel);
64 } else {
65 nrf_gpio_pin_clear(rf_sw_sel);
66 }
67
68 if(rf_sw_power_on) {
69 nrf_gpio_pin_set(rf_sw_pwr);
70 } else {
71 nrf_gpio_pin_clear(rf_sw_pwr);
72 }
73}
74/*---------------------------------------------------------------------------*/
75void
76platform_init_board(void)
77{
78 /* The XIAO routes the 2.4 GHz path through an external RF switch.
79 * Power the switch and default to the onboard ceramic antenna (RF1). */
80 rf_sw_external = false;
81 rf_sw_power_on = true;
82 rf_switch_apply();
83}
84/*---------------------------------------------------------------------------*/
85void
86platform_init_board_stage_two(void)
87{
88#if BUILD_WITH_SHELL
89 process_start(&xiao_nrf54l15_rf_switch_shell_process, NULL);
90#endif
91}
92#if BUILD_WITH_SHELL
93/*---------------------------------------------------------------------------*/
94static void
95rf_switch_print_status(shell_output_func output)
96{
97 const char *path = rf_sw_external ? "external" : "ceramic";
98 const char *power = rf_sw_power_on ? "on" : "off";
99 uint32_t rf_sw_sel =
100 NRF_GPIO_PIN_MAP(XIAO_NRF54L15_RF_SW_SEL_PORT, XIAO_NRF54L15_RF_SW_SEL_PIN);
101 uint32_t rf_sw_pwr =
102 NRF_GPIO_PIN_MAP(XIAO_NRF54L15_RF_SW_PWR_PORT, XIAO_NRF54L15_RF_SW_PWR_PIN);
103
104 SHELL_OUTPUT(output,
105 "RF switch: path=%s power=%s raw(sel=%u pwr=%u)\n",
106 path, power,
107 (unsigned)nrf_gpio_pin_read(rf_sw_sel),
108 (unsigned)nrf_gpio_pin_read(rf_sw_pwr));
109}
110/*---------------------------------------------------------------------------*/
111static PT_THREAD(cmd_rf_switch(struct pt *pt, shell_output_func output, char *args))
112{
113 char *next_args;
114
115 PT_BEGIN(pt);
116
117 SHELL_ARGS_INIT(args, next_args);
118 SHELL_ARGS_NEXT(args, next_args);
119
120 if(args == NULL || !strcmp(args, "status")) {
121 rf_switch_print_status(output);
122 PT_EXIT(pt);
123 }
124
125 if(!strcmp(args, "ceramic")) {
126 rf_sw_external = false;
127 rf_sw_power_on = true;
128 rf_switch_apply();
129 rf_switch_print_status(output);
130 PT_EXIT(pt);
131 }
132
133 if(!strcmp(args, "external")) {
134 rf_sw_external = true;
135 rf_sw_power_on = true;
136 rf_switch_apply();
137 rf_switch_print_status(output);
138 PT_EXIT(pt);
139 }
140
141 if(!strcmp(args, "power")) {
142 SHELL_ARGS_NEXT(args, next_args);
143 if(args == NULL) {
144 rf_switch_print_status(output);
145 PT_EXIT(pt);
146 }
147
148 if(!strcmp(args, "1") || !strcmp(args, "on")) {
149 rf_sw_power_on = true;
150 rf_switch_apply();
151 rf_switch_print_status(output);
152 PT_EXIT(pt);
153 }
154
155 if(!strcmp(args, "0") || !strcmp(args, "off")) {
156 rf_sw_power_on = false;
157 rf_switch_apply();
158 rf_switch_print_status(output);
159 PT_EXIT(pt);
160 }
161
162 SHELL_OUTPUT(output, "Usage: rf-sw power [0|1|off|on]\n");
163 PT_EXIT(pt);
164 }
165
166 SHELL_OUTPUT(output, "Usage: rf-sw status|ceramic|external|power [0|1|off|on]\n");
167 PT_END(pt);
168}
169/*---------------------------------------------------------------------------*/
170PROCESS_THREAD(xiao_nrf54l15_rf_switch_shell_process, ev, data)
171{
172 static struct etimer register_timer;
173
175
176 /* Register after serial_shell_init() has had a chance to call shell_init(). */
177 etimer_set(&register_timer, 1);
179 shell_command_set_register(&rf_switch_shell_set);
180
181 PROCESS_END();
182}
183/*---------------------------------------------------------------------------*/
184#endif
Event timer header file.
static bool etimer_expired(struct etimer *et)
Check if an event timer has expired.
Definition etimer.h:201
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
Definition etimer.c:177
#define PROCESS(name, strname)
Declare a process.
Definition process.h:309
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition process.h:122
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Definition process.h:159
#define PROCESS_END()
Define the end of a process.
Definition process.h:133
void process_start(struct process *p, process_data_t data)
Start a process.
Definition process.c:121
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition process.h:275
#define PT_BEGIN(pt)
Declare the start of a protothread inside the C function implementing the protothread.
Definition pt.h:280
#define PT_THREAD(name_args)
Declaration of a protothread.
Definition pt.h:265
#define PT_END(pt)
Declare the end of a protothread.
Definition pt.h:292
#define PT_EXIT(pt)
Exit the protothread.
Definition pt.h:411
Main header file for the Contiki shell.
Main header file for the Contiki shell.
A timer.
Definition etimer.h:79