SatNOGS-COMMS  4.1.0
A COMMS subsystem for CubeSats
Loading...
Searching...
No Matches
bsp.cpp
Go to the documentation of this file.
1/*
2 * SatNOGS-COMMS MCU software
3 *
4 * Copyright (C) 2024, 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#include "bsp.hpp"
22#include "../error_handler.hpp"
24
25namespace scl = satnogs::comms::lib;
26
28{
29
30/* spi_bsp Class Method Definitions */
31spi_bsp::spi_bsp(const struct device *dev, const struct spi_config &spi_cfg)
32 : m_dev(dev), m_spi_cfg(spi_cfg)
33{
34 k_mutex_init(&m_mtx);
35}
36
37void
38spi_bsp::read(uint8_t *rx, const uint8_t *tx, size_t tx_len, size_t rx_len)
39{
40 auto &err = error_handler::get_instance();
41 scoped_lock lock(&m_mtx);
42
43 struct spi_buf tx_buf = {.buf = const_cast<uint8_t *>(tx), .len = tx_len};
44 struct spi_buf rx_buf = {.buf = const_cast<uint8_t *>(rx), .len = rx_len};
45
46 struct spi_buf_set tx_bufs = {
47 .buffers = &tx_buf,
48 .count = 1,
49 };
50 struct spi_buf_set rx_bufs = {
51 .buffers = &rx_buf,
52 .count = 1,
53 };
54
55 int ret = spi_transceive(m_dev, &m_spi_cfg, &tx_bufs, &rx_bufs);
56 err.assert_error<spi_bsp_exception>((ret == 0), __FILE__, __LINE__);
57}
58
59void
60spi_bsp::write(const uint8_t *tx, size_t len)
61{
62 auto &err = error_handler::get_instance();
63 scoped_lock lock(&m_mtx);
64
65 struct spi_buf tx_buf = {.buf = const_cast<uint8_t *>(tx), .len = len};
66 struct spi_buf_set tx_bufs = {
67 .buffers = &tx_buf,
68 .count = 1,
69 };
70
71 int ret = spi_transceive(m_dev, &m_spi_cfg, &tx_bufs, nullptr);
72 err.assert_error<spi_bsp_exception>((ret == 0), __FILE__, __LINE__);
73}
74
75/* i2c_bsp Class Method Definitions */
76
77i2c_bsp::i2c_bsp(const struct device *i2c_dev) : i2c(), m_i2c(i2c_dev) {}
78
79void
80i2c_bsp::read(uint16_t addr, uint8_t *rx, size_t rxlen, const uint8_t *tx,
81 size_t txlen)
82{
83 auto &err = error_handler::get_instance();
84
85 if (CONFIG_ENABLE_I2C_REVOVERY) {
86 size_t retries = 0;
87 int ret = -1;
88 while (retries < CONFIG_I2C_RECOVERY_RETRIES && ret < 0) {
89 ret = i2c_write_read(m_i2c, addr, tx, txlen, rx, rxlen);
90 if (!ret) {
91 return;
92 }
93 i2c_recover_bus(m_i2c);
94 retries++;
95 }
96 err.assert_error<i2c_bsp_exception>((ret == 0), __FILE__, __LINE__);
97 } else {
98 int ret = i2c_write_read(m_i2c, addr, tx, txlen, rx, rxlen);
99 err.assert_error<i2c_bsp_exception>((ret == 0), __FILE__, __LINE__);
100 }
101}
102
103void
104i2c_bsp::read(uint16_t addr, uint8_t start_addr, uint8_t *rx, size_t len)
105{
106 auto &err = error_handler::get_instance();
107
108 if (CONFIG_ENABLE_I2C_REVOVERY) {
109 size_t retries = 0;
110 int ret = -1;
111 while (retries < CONFIG_I2C_RECOVERY_RETRIES && ret < 0) {
112 ret = i2c_burst_read(m_i2c, addr, start_addr, rx, len);
113 if (!ret) {
114 return;
115 }
116 i2c_recover_bus(m_i2c);
117 retries++;
118 }
119 err.assert_error<i2c_bsp_exception>((ret == 0), __FILE__, __LINE__);
120 } else {
121 int ret = i2c_burst_read(m_i2c, addr, start_addr, rx, len);
122 err.assert_error<i2c_bsp_exception>((ret == 0), __FILE__, __LINE__);
123 }
124}
125
126void
127i2c_bsp::write(uint16_t addr, const uint8_t *tx, size_t len)
128{
129 auto &err = error_handler::get_instance();
130 int ret = i2c_write(m_i2c, tx, len, addr);
131 err.assert_error<i2c_bsp_exception>((ret == 0), __FILE__, __LINE__);
132}
133
134void
135i2c_bsp::write(uint16_t addr, uint8_t start_addr, const uint8_t *tx, size_t len)
136{
137 auto &err = error_handler::get_instance();
138 int ret = i2c_burst_write(m_i2c, addr, start_addr, tx, len);
139 err.assert_error<i2c_bsp_exception>((ret == 0), __FILE__, __LINE__);
140}
141
151const struct device *
153{
154 return m_i2c;
155}
156
157/* adc_bsp Class Method Definitions */
158
159adc_bsp::adc_bsp(const struct adc_dt_spec &adc_channel)
160 : adc(adc_channel.resolution, adc_ref_internal(adc_channel.dev) / 1000.0f),
161 m_adc_channel(adc_channel),
162 m_adc_sample(0U),
163 m_sequence({.buffer = &m_adc_sample, .buffer_size = sizeof(m_adc_sample)})
164{
165 int err;
166 auto &err_hdl = error_handler::get_instance();
167
168 if (!adc_is_ready_dt(&m_adc_channel)) {
169 err_hdl.assert_error<adc_initialization_exception>(__FILE__, __LINE__);
170 }
171
172 err = adc_channel_setup_dt(&m_adc_channel);
173 if (err != 0) {
174 err_hdl.assert_error<adc_initialization_exception>(__FILE__, __LINE__);
175 }
176
177 err = adc_sequence_init_dt(&m_adc_channel, &m_sequence);
178 if (err != 0) {
179 err_hdl.assert_error<adc_initialization_exception>(__FILE__, __LINE__);
180 }
181}
182
183void
185{
186}
187
188void
190{
191}
192
193uint32_t
195{
196 adc_read_dt(&m_adc_channel, &m_sequence);
197 return m_adc_sample;
198}
199
200float
202{
203 int32_t val_mv = read();
204 adc_raw_to_millivolts_dt(&m_adc_channel, &val_mv);
205 return val_mv / 1000.0f;
206}
207
208/* sensor_bsp Class Method Definitions */
209
210sensor_bsp::sensor_bsp(const struct device *dev) : sensor(), m_dev(dev)
211{
212 if (!device_is_ready(dev)) {
213 auto &err = error_handler::get_instance();
214 err.assert_error<device_not_ready_exception>(__FILE__, __LINE__);
215 }
216}
217
218float
220{
221 auto &err = error_handler::get_instance();
222 struct sensor_value val;
223 int rc;
224
225 rc = sensor_sample_fetch(m_dev);
226 if (rc) {
227 err.assert_error<v_bat_exception>(__FILE__, __LINE__);
228 }
229
230 rc = sensor_channel_get(m_dev, SENSOR_CHAN_VOLTAGE, &val);
231 if (rc) {
232 err.assert_error<v_bat_exception>(__FILE__, __LINE__);
233 }
234
235 return sensor_value_to_double(&val);
236}
237
238float
240{
241 return 0;
242}
243
244} // namespace satnogs::comms
void stop()
Stops the ADC.
Definition bsp.cpp:189
uint32_t read()
Get the ADC value.
Definition bsp.cpp:194
float voltage()
Get the ADC voltage.
Definition bsp.cpp:201
void start()
Starts the ADC.
Definition bsp.cpp:184
adc_bsp(const struct adc_dt_spec &adc_channel)
Definition bsp.cpp:159
static error_handler & get_instance()
Singleton access to the error_handler subsystem.
const struct device * dev()
Get the I2C device.
Definition bsp.cpp:152
void read(uint16_t addr, uint8_t *rx, size_t rxlen, const uint8_t *tx, size_t txlen)
Performs an I2C read operation.
Definition bsp.cpp:80
void write(uint16_t addr, const uint8_t *tx, size_t len)
Performs an I2C write operation.
Definition bsp.cpp:127
i2c_bsp(const struct device *i2c_dev)
Definition bsp.cpp:77
adc(uint16_t resolution, float vref)
Construct a new ADC object.
Definition adc.hpp:47
uint32_t resolution() const
Get the ADC resolution.
Definition adc.hpp:90
i2c()
Construct a new I2C object.
Definition i2c.hpp:45
sensor()
Construct a new sensor object.
Definition sensor.hpp:47
Implements a scoped lock utilizing the Zephyr mutex.
float vref()
Get the VREF from SoCs designated internal ADC channel.
Definition bsp.cpp:239
float vbat()
Get the VBAT from SoCs designated internal ADC channel.
Definition bsp.cpp:219
sensor_bsp(const struct device *dev)
Definition bsp.cpp:210
void read(uint8_t *rx, const uint8_t *tx, size_t tx_len, size_t rx_len) override
Performs an SPI read operation.
Definition bsp.cpp:38
spi_bsp(const struct device *dev, const struct spi_config &spi_cfg)
Definition bsp.cpp:31
void write(const uint8_t *tx, size_t len) override
Performs an SPI write operation.
Definition bsp.cpp:60