SatNOGS-COMMS  4.1.0
A COMMS subsystem for CubeSats
Loading...
Searching...
No Matches
rf_frontend24.cpp
Go to the documentation of this file.
1/*
2 * SatNOGS-COMMS control library
3 *
4 * Copyright (C) 2022-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
25
26namespace satnogs::comms::lib
27{
28
29/* Re-implementation of the RFFC2071 driver weak functions */
30extern "C" {
31
32int
33rffcx07x_set_enx(struct rffcx07x *h, uint8_t enable)
34{
35 if (h->enx_gpio_dev) {
36 bsp::gpio *enx_gpio_dev = static_cast<bsp::gpio *>(h->enx_gpio_dev);
37 enx_gpio_dev->set(enable);
38 }
39 return RFFCX07X_NO_ERROR;
40}
41
42int
43rffcx07x_set_enbl(struct rffcx07x *h, uint8_t enable)
44{
45 return RFFCX07X_NO_ERROR;
46}
47
48int
49rffcx07x_set_resetx(struct rffcx07x *h, uint8_t enable)
50{
51 if (h->rst_gpio_dev) {
52 bsp::gpio *rst_gpio_dev = static_cast<bsp::gpio *>(h->rst_gpio_dev);
53 rst_gpio_dev->set(enable);
54 }
55 return RFFCX07X_NO_ERROR;
56}
57
58int
59rffcx07x_set_mode(struct rffcx07x *h, uint8_t enable)
60{
61 return RFFCX07X_NO_ERROR;
62}
63
64int
65rffcx07x_set_clk(struct rffcx07x *h, uint8_t enable)
66{
67 if (h->clk_dev) {
68 bsp::gpio *clk_dev = static_cast<bsp::gpio *>(h->clk_dev);
69 clk_dev->set(enable);
70 }
71 return RFFCX07X_NO_ERROR;
72}
73
74int
75rffcx07x_set_sda(struct rffcx07x *h, uint8_t enable)
76{
77 if (h->sda_gpio_dev) {
78 bsp::gpio *sda_gpio_dev = static_cast<bsp::gpio *>(h->sda_gpio_dev);
79 sda_gpio_dev->set(enable);
80 }
81 return RFFCX07X_NO_ERROR;
82}
83
84int
85rffcx07x_get_sda(struct rffcx07x *h)
86{
87 if (h->sda_gpio_dev) {
88 bsp::gpio *sda_gpio_dev = static_cast<bsp::gpio *>(h->sda_gpio_dev);
89 return sda_gpio_dev->get();
90 }
91 return -RFFCX07X_NOT_IMPL;
92}
93
94int
95rffcx07x_set_sda_dir(struct rffcx07x *h, rffcx07x_sda_dir_t dir)
96{
97 if (h->sda_gpio_dev) {
98 bsp::gpio *sda_gpio_dev = static_cast<bsp::gpio *>(h->sda_gpio_dev);
99 if (dir == RFFCX07X_SDA_RX) {
101 } else {
103 }
104 }
105 return RFFCX07X_NO_ERROR;
106}
107
108void
109rffcx07x_en_irq(struct rffcx07x *h, uint8_t enable)
110{
111 return;
112}
113
114void
115rffcx07x_delay_us(struct rffcx07x *h, uint32_t us)
116{
117 bsp::chrono *chrono_dev = static_cast<bsp::chrono *>(h->user_dev0);
118 chrono_dev->delay_us(us);
119}
120}
121
133 power &pwr)
134 : rf_frontend(init_params, {io.en_agc, io.agc_vset, io.flt_sel}, pwr),
135 m_chrono(io.chrono)
136{
137 m_mixer.clk_dev = &io.mixer_clk;
138 m_mixer.rst_gpio_dev = &io.mixer_rst;
139 m_mixer.enx_gpio_dev = &io.mixer_enx;
140 m_mixer.sda_gpio_dev = &io.mixer_sda;
141 m_mixer.user_dev0 = &io.chrono;
142 enable(false);
143}
144
155void
157{
158 int ret = 0;
159 m_pwr.enable(power::subsys::SBAND, set);
160 if (set) {
161 ret = rffcx07x_init(&m_mixer, 26000000, 2000000, RFFCX07X_HD);
162 ret += rffcx07x_set_gate(&m_mixer, 1);
163 ret += rffcx07x_set_lock_gpo(&m_mixer, 1);
164 if (ret) {
165 throw rf_frontend24_exception(__FILE__, __LINE__);
166 }
167 } else {
168 /* Explicitly set the ENBL and RESETX to 0, because the mixer can
169 * parasitically still operate */
170 rffcx07x_set_enx(&m_mixer, 0);
171 rffcx07x_set_resetx(&m_mixer, 0);
172 }
173}
174
181bool
183{
184 return m_pwr.enabled(power::subsys::SBAND);
185}
186
193void
195{
196 int ret = 0;
197 switch (d) {
198 case dir::RX:
199 m_dir = d;
200 ret += rffcx07x_enable(&m_mixer, 0, RFFCX07X_PATH2, 1);
201 ret += rffcx07x_set_mix_current(&m_mixer, 2, RFFCX07X_PATH1);
202 ret += rffcx07x_set_freq(&m_mixer, lo_freq, RFFCX07X_PATH1);
203 ret += rffcx07x_enable(&m_mixer, 1, RFFCX07X_PATH1, 1);
204 if (ret) {
205 throw rf_frontend24_exception(__FILE__, __LINE__);
206 }
207
208 if (mixer_lock() == false) {
209 throw mixer_lock_exception(__FILE__, __LINE__);
210 }
211 break;
212 case dir::TX:
213 m_dir = d;
214 m_agc.enable(false);
215 m_dac.stop();
216 ret += rffcx07x_enable(&m_mixer, 0, RFFCX07X_PATH1, 1);
217 ret = rffcx07x_set_mix_current(&m_mixer, 2, RFFCX07X_PATH2);
218 ret += rffcx07x_set_freq(&m_mixer, lo_freq, RFFCX07X_PATH2);
219 ret += rffcx07x_enable(&m_mixer, 1, RFFCX07X_PATH2, 1);
220 if (ret) {
221 throw rf_frontend24_exception(__FILE__, __LINE__);
222 }
223
224 if (mixer_lock() == false) {
225 throw mixer_lock_exception(__FILE__, __LINE__);
226 }
227 break;
228 default:
229 throw inval_arg_exception(__FILE__, __LINE__);
230 break;
231 }
232}
233
246bool
248{
249 uint8_t lock = false;
250 int ret = rffcx07x_get_lock(&m_mixer, &lock);
251 return lock && ret == RFFCX07X_NO_ERROR;
252}
253
254} // namespace satnogs::comms::lib
Chrono device abstraction.
Definition chrono.hpp:41
virtual void delay_us(size_t us)=0
Delays the execution of the active task for at least us microseconds.
GPIO device abstraction.
Definition gpio.hpp:38
virtual void set(bool s)=0
Sets the logical output of the pin. For example, if the pin has been configured as active low,...
virtual bool get()=0
Gets the logical level of the GPIO pin. For example, if the pin has been configured as active low,...
@ OUTPUT
GPIO pin is configured as output.
Definition gpio.hpp:43
@ INPUT
GPIO pin is configured as input.
Definition gpio.hpp:42
virtual void set_direction(direction dir)=0
Set the direction of the GPIO.
Generic exception indicating an invalid argument.
Exception occurred when the RF mixer fails to lock.
Manages power supplies and monitors subsystem status.
Definition power.hpp:43
IO configuration for controlling the various peripherals of the S-Band frontend.
Exception for the S-Band RF-frontend.
void set_direction(dir d, uint64_t lo_freq)
rf_frontend24(const params &init_params, const io_conf &io, power &pwr)
Construct a new rf frontend24::rf frontend24 object that controls the S-Band RF frontend interface.
bool mixer_lock()
Checks if the RF mixer has acquired a lock.
bool enabled() const
Checks if the S-Band RF frontend is enabled.
RF frontend initialization settings.
rf_frontend(const params &init_params, io_conf &&io, power &pwr)
int rffcx07x_set_sda_dir(struct rffcx07x *h, rffcx07x_sda_dir_t dir)
int rffcx07x_set_mode(struct rffcx07x *h, uint8_t enable)
void rffcx07x_en_irq(struct rffcx07x *h, uint8_t enable)
int rffcx07x_set_clk(struct rffcx07x *h, uint8_t enable)
void rffcx07x_delay_us(struct rffcx07x *h, uint32_t us)
int rffcx07x_set_enbl(struct rffcx07x *h, uint8_t enable)
int rffcx07x_set_enx(struct rffcx07x *h, uint8_t enable)
int rffcx07x_get_sda(struct rffcx07x *h)
int rffcx07x_set_sda(struct rffcx07x *h, uint8_t enable)
int rffcx07x_set_resetx(struct rffcx07x *h, uint8_t enable)