SatNOGS-COMMS  4.1.0
A COMMS subsystem for CubeSats
Loading...
Searching...
No Matches
antenna_isis.hpp
Go to the documentation of this file.
1/*
2 * SatNOGS-COMMS control library
3 *
4 * Copyright (C) 2025, 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 <cstdint>
25#include <initializer_list>
29
30namespace satnogs::comms::lib
31{
32
41template <uint32_t N> class antenna_isis : public antenna
42{
43public:
44 enum class cmd : uint8_t
45 {
46 CANCEL = 0xA9,
47 DISARM = 0xAC,
48 ARM = 0xAD,
55 UPTIME = 0xC6,
56 ALL = 0xC7
57 };
58
67 antenna_isis(const etl::istring &name, bsp::i2c &i2c, uint16_t addr,
68 bsp::gpio &pwr)
69 : antenna(name, N), m_addr(addr), m_i2c(i2c), m_pwr(pwr)
70 {
71 static_assert(N > 0, "At least one IO configuration should be set");
72 }
73
74 void
75 enable(bool en) override
76 {
77 m_pwr.set(en);
78 }
79
80 bool
81 detect(uint32_t idx) override
82 {
83 bool x = false;
85 return x;
86 }
87
88 void
89 deploy(uint32_t idx, bool en) override
90 {
91 if (idx > 1) {
92 throw scl::inval_arg_exception(__FILE__, __LINE__);
93 }
94
95 std::array<uint8_t, 4> txbuf{};
96 if (en) {
97 /* To deploy the any of the antennas, the system should be armed */
98 txbuf[0] = static_cast<uint8_t>(cmd::ARM);
99 m_i2c.write(m_addr, txbuf.data(), 1);
100 txbuf[0] = static_cast<uint8_t>(idx == 0 ? cmd::DEPLOY_ANT1_OVERRIDE
102 /* Use safety time */
103 txbuf[1] = 0;
104 m_i2c.write(m_addr, txbuf.data(), 2);
105 } else {
106 txbuf[0] = static_cast<uint8_t>(cmd::CANCEL);
107 m_i2c.write(m_addr, txbuf.data(), 1);
108 txbuf[0] = static_cast<uint8_t>(cmd::DISARM);
109 m_i2c.write(m_addr, txbuf.data(), 1);
110 }
111 }
112
113 void
114 telemetry(tlm t, uint32_t &res)
115 {
116 std::array<uint8_t, 4> txbuf{};
117 std::array<uint8_t, 4> rxbuf{};
118
119 switch (t) {
120 case tlm::UPTIME:
121 txbuf[0] = static_cast<uint8_t>(cmd::UPTIME);
122 m_i2c.read(m_addr, rxbuf.data(), 4, txbuf.data(), 1);
123 res = (rxbuf[3] << 24) | (rxbuf[2] << 16) | (rxbuf[1] << 8) | rxbuf[0];
124 break;
125 default:
126 throw scl::inval_arg_exception(__FILE__, __LINE__);
127 }
128 }
129
130 void
131 telemetry(tlm t, float &res) override
132 {
133
134 std::array<uint8_t, 2> txbuf{};
135 std::array<uint8_t, 11> rxbuf{};
136
137 switch (t) {
138 case tlm::TEMPERATURE: {
139 txbuf[0] = static_cast<uint8_t>(cmd::TEMPERATURE);
140 m_i2c.read(m_addr, rxbuf.data(), 2, txbuf.data(), 1);
141 uint32_t x = (rxbuf[1] << 8) | rxbuf[0];
142 /* Only 10-bits are relevant */
143 x &= 0x3FF;
144 double mV = (3.3 / 1024) * x * 1000.0;
145 /*
146 * Convert to Celsius. Slope and intercept point has been calculated by
147 * linear regression of the Table 8-2 of the ICD
148 */
149 res = mV * -0.09067242916 + 190.15431352;
150 break;
151 }
152 case tlm::VOLTAGE: {
153 txbuf[0] = static_cast<uint8_t>(cmd::ALL);
154 m_i2c.read(m_addr, rxbuf.data(), 11, txbuf.data(), 1);
155 uint32_t x = (rxbuf[3] << 8) | rxbuf[2];
156 /* Only 10-bits are relevant */
157 x &= 0x3FF;
158 /*
159 * Fullscale empirically retrieved after measuring the voltage on the
160 * connector of the antenna taking into account the cable voltage drop.
161 * The datasheet does not specify the correct formula.
162 */
163 res = (20.0 / 1024.0) * x;
164 break;
165 }
166
167 default:
168 throw scl::inval_arg_exception(__FILE__, __LINE__);
169 }
170 }
171
172 void
173 telemetry(tlm t, uint32_t idx, bool &res) override
174 {
175
176 std::array<uint8_t, 4> txbuf{};
177 std::array<uint8_t, 4> rxbuf{};
178
179 if (idx > 1) {
180 throw scl::inval_arg_exception(__FILE__, __LINE__);
181 }
182
183 switch (t) {
184 case tlm::DEPLOYED: {
185 txbuf[0] = static_cast<uint8_t>(cmd::DEPLOYMENT_STATUS);
186 m_i2c.read(m_addr, rxbuf.data(), 2, txbuf.data(), 1);
187 /* Switch has inverted logic */
188 if (idx == 0) {
189 res = !(rxbuf[1] >> 7);
190 } else {
191 res = !((rxbuf[1] >> 3) & 0x1);
192 }
193 break;
194 }
195 default:
196 throw scl::inval_arg_exception(__FILE__, __LINE__);
197 }
198 }
199
200private:
201 const uint16_t m_addr;
202 bsp::i2c &m_i2c;
203 bsp::gpio &m_pwr;
204};
205
207} // namespace satnogs::comms::lib
antenna_isis(const etl::istring &name, bsp::i2c &i2c, uint16_t addr, bsp::gpio &pwr)
Construct a new antenna_isis object.
void enable(bool en) override
Enables or disables the antenna subsystem if required.
void deploy(uint32_t idx, bool en) override
Deploy the antenna.
bool detect(uint32_t idx) override
Returns antenna deployment status.
void telemetry(tlm t, uint32_t &res)
void telemetry(tlm t, uint32_t idx, bool &res) override
void telemetry(tlm t, float &res) override
antenna(const char *name, uint32_t nelems)
Construct a new generic antenna object.
Definition antenna.cpp:34
const char * name() const
Retrieves the name of the antenna.
Definition antenna.cpp:89
GPIO device abstraction.
Definition gpio.hpp:38
I2C device abstraction.
Definition i2c.hpp:40
Generic exception indicating an invalid argument.