SatNOGS-COMMS  4.1.0
A COMMS subsystem for CubeSats
Loading...
Searching...
No Matches
io.hpp
Go to the documentation of this file.
1/*
2 * SatNOGS-COMMS MCU software
3 *
4 * Copyright (C) 2023, Libre Space Foundation <http://libre.space>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * SPDX-License-Identifier: GNU General Public License v3.0 or later
20 */
21
22#pragma once
23
24#include "callbacks.hpp"
25#include "error_handler.hpp"
26#include "msg_arbiter.hpp"
27#include "settings.hpp"
28#include <cstddef>
29#include <cstdint>
30#include <cstring>
31#include <etl/to_string.h>
35#include <utils/iface_ctrl.hpp>
36#include <zephyr/canbus/isotp.h>
37#include <zephyr/drivers/uart.h>
38#include <zephyr/kernel.h>
39#include <zephyr/task_wdt/task_wdt.h>
40
41namespace scl = satnogs::comms::lib;
42
43namespace satnogs::comms
44{
45
46class io
47{
48public:
49 class uart
50 {
51 public:
52 /* Reduce the memory footprint by using the bounching buffer option of the
53 * async API*/
54 static constexpr size_t buf_len = CONFIG_MAX_MTU / 2;
55 enum class identifier : uint8_t
56 {
58 };
59
60 uart(identifier id) : id(id), buf_idx(0), msg_idx(0) {};
61
63 uint8_t buf_idx;
64 uint32_t msg_idx;
65 uint8_t buf[2][buf_len];
67 };
68
69 class radio
70 {
71 public:
72 friend io;
74 : m_uhf(scl::radio::interface::UHF),
75 m_sband(scl::radio::interface::SBAND)
76 {
77 k_mutex_init(&m_mtx);
78 }
79
80 void
82 {
83 scoped_lock lock(m_mtx);
85 radio.enable();
86 m_uhf.enable();
87 m_sband.enable();
88 }
89
90 void
91 enable(scl::radio::interface iface, bool yes = true)
92 {
93 scoped_lock lock(m_mtx);
94 switch (iface) {
96 m_uhf.enable(yes);
97 break;
99 m_sband.enable(yes);
100 break;
101 default:
102 return;
103 }
104 }
105
106 void
108 {
109 enable(iface, false);
110 }
111
112 void
114 {
115 scoped_lock lock(m_mtx);
117 m_uhf.disable();
118 m_sband.disable();
119 radio.enable(false);
120 }
121
122 int
123 rx(scl::radio::rx_msg &msg, uint32_t timeout_ms)
124 {
126 return radio.recv_msg(msg, timeout_ms);
127 }
128
129 void
131 bool more = false)
132 {
133 scoped_lock lock(m_mtx);
134 switch (iface) {
136 m_uhf.tx(msg, more);
137 break;
139 m_sband.tx(msg, more);
140 break;
141 default:
142 return;
143 }
144 }
145
146 void
148 {
149 scoped_lock lock(m_mtx);
150 switch (iface) {
152 m_uhf.reset_stats();
153 break;
155 m_sband.reset_stats();
156 break;
157 default:
158 return;
159 }
160 }
161
162 const utils::iface_ctrl &
164 {
165 return m_uhf;
166 }
167
168 const utils::iface_ctrl &
170 {
171 return m_sband;
172 }
173
174 private:
175 utils::iface_ctrl m_uhf;
176 utils::iface_ctrl m_sband;
177 struct k_mutex m_mtx;
178 };
179
180 static io &
182 {
183 static io instance;
184 return instance;
185 }
186
187 /* Singleton */
188 io(io const &) = delete;
189
190 void
191 operator=(io const &) = delete;
192
193 radio &
194 radio_ctrl();
195
196 void
197 start();
198
199private:
200 static void
201 can1_tx_thread(void *arg1, void *arg2, void *arg3);
202
203 static void
204 can1_rx_thread(void *arg1, void *arg2, void *arg3);
205
206 static void
207 can2_rx_thread(void *arg1, void *arg2, void *arg3);
208
209 static void
210 can2_tx_thread(void *arg1, void *arg2, void *arg3);
211
212 static void
213 radio_rx_thread(void *arg1, void *arg2, void *arg3);
214
215 static void
216 uhf_tx_thread(void *arg1, void *arg2, void *arg3);
217
218 static void
219 sband_tx_thread(void *arg1, void *arg2, void *arg3);
220
221 void
222 radio_rx_drop_callback(scl::radio::interface iface);
223
224 void
225 update_radio_rx_stats(scl::radio::interface iface, bool valid, float rssi);
226
227 io() = default;
228
229 radio m_radio;
230 k_tid_t m_can1_tx_tid;
231 k_tid_t m_can1_rx_tid;
232 k_tid_t m_can2_tx_tid;
233 k_tid_t m_can2_rx_tid;
234 k_tid_t m_radio_rx_tid;
235 k_tid_t m_uhf_tx_tid;
236 k_tid_t m_sband_tx_tid;
237 uint32_t m_can1_rx_cnt;
238 uint32_t m_can1_tx_cnt;
239 uint32_t m_usart3_rx_cnt;
240 uint32_t m_usart3_tx_cnt;
241};
242
244{
245public:
246 can_enable_exception(string_type file_name, numeric_type line)
247 : scl::exception(
248 scl::exception::severity::MAJOR, file_name, line,
249 error_msg{"Could not enable CAN device", "canenbl", ECANENBL})
250 {
251 }
252};
253
255{
256public:
257 isotp_bind_exception(string_type file_name, numeric_type line)
258 : scl::exception(scl::exception::severity::MINOR, file_name, line,
259 error_msg{"Could not bind the ISOTP device", "isotpbind",
260 EISOTPBIND})
261 {
262 }
263};
264
266{
267public:
268 isotp_recv_exception(string_type file_name, numeric_type line)
269 : scl::exception(scl::exception::severity::MINOR, file_name, line,
270 error_msg{"Could not receive from ISOTP device",
271 "isotprecv", EISOTPRECV})
272 {
273 }
274};
275
276} // namespace satnogs::comms
can_enable_exception(string_type file_name, numeric_type line)
Definition io.hpp:246
void disable(scl::radio::interface iface)
Definition io.hpp:107
void reset_stats(scl::radio::interface iface)
Definition io.hpp:147
void enable(scl::radio::interface iface, bool yes=true)
Definition io.hpp:91
void tx(scl::radio::interface iface, const msg_arbiter::msg &msg, bool more=false)
Definition io.hpp:130
int rx(scl::radio::rx_msg &msg, uint32_t timeout_ms)
Definition io.hpp:123
const utils::iface_ctrl & uhf()
Definition io.hpp:163
const utils::iface_ctrl & sband()
Definition io.hpp:169
static constexpr size_t buf_len
Definition io.hpp:54
uart(identifier id)
Definition io.hpp:60
const identifier id
Definition io.hpp:62
uint8_t buf[2][buf_len]
Definition io.hpp:65
msg_arbiter::msg msg
Definition io.hpp:66
void operator=(io const &)=delete
io(io const &)=delete
static io & get_instance()
Definition io.hpp:181
radio & radio_ctrl()
Definition io.cpp:139
isotp_bind_exception(string_type file_name, numeric_type line)
Definition io.hpp:257
isotp_recv_exception(string_type file_name, numeric_type line)
Definition io.hpp:268
comms::lib::radio & radio()
Returns a reference to the radio subsystem.
Definition board.cpp:80
static board & get_instance()
Gets a reference to the single instance of the Board interface class.
Definition board.cpp:66
A class representing error messages in the SatNOGS-COMMS system.
Definition exception.hpp:83
Exception base class.
Definition exception.hpp:63
severity
Severity levels of exceptions.
Definition exception.hpp:71
@ MINOR
Failure having minimal impact.
Definition exception.hpp:75
@ MAJOR
Failure causing minor mission degradation.
Definition exception.hpp:74
exception(severity sev, const char *file, int lineno, const error_msg &err_msg)
Constructor for the exception class.
The RX message accompanied by its metadata.
Definition radio.hpp:289
interface
Radio interface identifier.
Definition radio.hpp:177
Implements a scoped lock utilizing the Zephyr mutex.
#define ECANENBL
Error in enabling CAN device.
#define EISOTPBIND
Error in ISOTP device binding.
#define EISOTPRECV
Error in receiving from ISOTP device.