GCC Code Coverage Report


Directory: ../../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 79
Functions: 0.0% 0 / 0 / 3
Branches: 0.0% 0 / 0 / 46

driver/lora/lora_async.c
Line Branch Exec Source
1 /*******************************************************************************
2 *
3 * FILE:
4 * lora_async.c
5 *
6 * DESCRIPTION:
7 * Contains API functions for transmating //{POSTPONED} and receiving//
8 * from the board's built-in LoRa module in non-blocking mode.
9 *
10 * COPYRIGHT:
11 * Copyright (c) 2025 Sun Devil Rocketry.
12 * All rights reserved.
13 *
14 * This software is licensed under terms that can be found in the LICENSE
15 * file in the root directory of this software component.
16 * If no LICENSE file comes with this software, it is covered under the
17 * BSD-3-Clause.
18 *
19 * https://opensource.org/license/bsd-3-clause
20 *
21 *******************************************************************************/
22
23
24 /*------------------------------------------------------------------------------
25 Standard Includes
26 ------------------------------------------------------------------------------*/
27 #include <string.h>
28
29 /*------------------------------------------------------------------------------
30 MCU Pins
31 ------------------------------------------------------------------------------*/
32 #if defined( FLIGHT_COMPUTER )
33 #include "sdr_pin_defines_A0002.h"
34 #include "led.h"
35 #elif defined( GROUND_STATION )
36 #include "sdr_pin_defines_A0005.h"
37 #include "led.h"
38 #elif defined( A0010 )
39 #include "sdr_pin_defines_A0010.h"
40 #include "led.h"
41 #endif
42
43 /*------------------------------------------------------------------------------
44 Project Includes
45 ------------------------------------------------------------------------------*/
46 #include "lora.h"
47 #include "telemetry.h"
48 #include "usb.h"
49 #include "main.h"
50
51 /*------------------------------------------------------------------------------
52 Global Variables
53 ------------------------------------------------------------------------------*/
54 static LORA_ASYNC_OP_MODE op_mode = LORA_ASYNC_OFF;
55 static LORA_TX_FSM_STATE tx_fsm = LORA_TX_STATE_BLOCKING;
56
57 static LORA_STATUS lora_status = LORA_OK;
58
59 /* tx globals */
60 static uint8_t register_contents[2] = {0x00, 0x00};
61 static TELEMETRY_MESSAGE payload;
62 static uint8_t burst_write_buf[TELEMETRY_MESSAGE_SIZE + 1];
63
64 /*------------------------------------------------------------------------------
65 Static Prototypes
66 ------------------------------------------------------------------------------*/
67
68 static void lora_tx_update
69 (
70 LORA_FSM_EVENT update_cause /* i: which kind of event triggered this update */
71 );
72
73 /*------------------------------------------------------------------------------
74 Procedures
75 ------------------------------------------------------------------------------*/
76
77 ✗ void lora_fsm_update
78 (
79 LORA_FSM_EVENT update_cause
80 )
81 {
82 ✗ switch ( op_mode )
83 {
84 ✗ case LORA_ASYNC_TX:
85 ✗ lora_tx_update( update_cause );
86 ✗ return;
87 default: /* any unhandled mode -- just return */
88 return;
89 }
90
91 } /* lora_fsm_update */
92
93
94 ✗ LORA_STATUS lora_fsm_set_mode
95 (
96 LORA_ASYNC_OP_MODE new_mode
97 )
98 {
99 /* Starting TX */
100 ✗ if( ( new_mode == LORA_ASYNC_TX )
101 ✗ && ( op_mode == LORA_ASYNC_OFF ) )
102 {
103 ✗ op_mode = LORA_ASYNC_TX;
104 ✗ tx_fsm = LORA_TX_STATE_BLOCKING;
105 }
106 /* Stopping TX */
107 ✗ else if( ( new_mode == LORA_ASYNC_OFF )
108 ✗ && ( op_mode == LORA_ASYNC_TX ) )
109 {
110 /* Signal to cancel */
111 ✗ lora_tx_update( LORA_FSM_EVENT_CANCEL );
112 }
113 else
114 {
115 ✗ lora_status = LORA_INVALID_CMD;
116 }
117
118 ✗ return lora_status;
119
120 } /* lora_fsm_set_mode */
121
122
123 /*********************************************************************************
124 * *
125 * FUNCTION: *
126 * lora_tx_update *
127 * *
128 * DESCRIPTION: *
129 * Update the lora async transmission FSM. *
130 * *
131 *********************************************************************************/
132 ✗ static void lora_tx_update
133 (
134 LORA_FSM_EVENT update_cause /* i: which kind of event triggered this update */
135 )
136 {
137 /* Local Variables */
138
139 /* precondition: lora is not broken */
140 ✗ if( ( lora_status & ( LORA_FAIL | LORA_TRANSMIT_FAIL | LORA_TIMEOUT_FAIL ) )
141 ✗ || ( update_cause == LORA_FSM_EVENT_CANCEL ) )
142 {
143 ✗ tx_fsm = LORA_TX_STATE_BLOCKING; /* cancel lora FSM */
144 ✗ op_mode = LORA_ASYNC_OFF; /* stop handling lora events */
145 ✗ return;
146 }
147
148 // ETS TEMP: Test
149 // telemetry_get_next_message();
150 // lora_transmit( &payload, sizeof( TELEMETRY_MESSAGE ) );
151 // return;
152
153 /* update the current telemetry state */
154 ✗ switch( tx_fsm )
155 {
156 ✗ case LORA_TX_STATE_BLOCKING: /* FSM start */
157 {
158 /* Assumptions: LoRa is initialized with valid configs, telem should only initialize
159 with a synchronous event from main loop. */
160 ✗ if( update_cause != LORA_FSM_EVENT_SYNCHRONOUS_UPDATE )
161 {
162 /* do nothing */
163 return;
164 }
165 ✗ tx_fsm = LORA_TX_STATE_STATUS_CHECK;
166 ✗ lora_status = lora_read_register_IT(LORA_REG_OPERATION_MODE, register_contents);
167 ✗ return;
168 }
169
170 ✗ case LORA_TX_STATE_STATUS_CHECK: /* check if in standby mode */
171 {
172 ✗ if( update_cause != LORA_FSM_EVENT_REG_READ_CPLT )
173 {
174 /* do nothing */
175 return;
176 }
177
178 /* check return. if not standby, cancel telem fsm and go back to blocking */
179 ✗ if ((register_contents[1] & 0b111) != LORA_STANDBY_MODE)
180 {
181 ✗ tx_fsm = LORA_TX_STATE_BLOCKING; /* wait for next synchronous check */
182 /* Preserve LoRa mode (bit 7) and other upper bits; only set mode. */
183 ✗ lora_status = lora_write_register_IT(
184 LORA_REG_OPERATION_MODE,
185 (uint8_t)( ( register_contents[1] & (uint8_t) ~0x7 ) | (uint8_t) LORA_STANDBY_MODE )
186 );
187 ✗ return;
188 }
189 else /* success: go to next state*/
190 {
191 ✗ tx_fsm = LORA_TX_STATE_GETTING_BUF;
192 ✗ lora_status = lora_read_register_IT(LORA_REG_FIFO_TX_BASE_ADDR, register_contents);
193 }
194 ✗ return;
195 }
196
197 ✗ case LORA_TX_STATE_GETTING_BUF: /* get fifo base ptr */
198 {
199 ✗ if( update_cause != LORA_FSM_EVENT_REG_READ_CPLT )
200 {
201 /* do nothing */
202 return;
203 }
204
205 ✗ tx_fsm = LORA_TX_STATE_SETTING_TX_BASE;
206 ✗ lora_status = lora_write_register_IT(LORA_REG_FIFO_SPI_POINTER, register_contents[1]);
207 ✗ return;
208 }
209
210 ✗ case LORA_TX_STATE_SETTING_TX_BASE: /* set tx base ptr */
211 {
212 ✗ if( update_cause != LORA_FSM_EVENT_WRITE_CPLT )
213 {
214 /* do nothing */
215 return;
216 }
217
218 ✗ tx_fsm = LORA_TX_STATE_WRITING_MSG_LEN;
219 ✗ lora_status = lora_write_register_IT(LORA_REG_SIGNAL_TO_NOISE, TELEMETRY_MESSAGE_SIZE);
220 ✗ return;
221 }
222
223 ✗ case LORA_TX_STATE_WRITING_MSG_LEN: /* write the length of the lora message */
224 {
225 ✗ if( update_cause != LORA_FSM_EVENT_WRITE_CPLT )
226 {
227 /* do nothing */
228 return;
229 }
230
231 ✗ tx_fsm = LORA_TX_STATE_WRITING_MSG;
232 ✗ telemetry_get_next_message(&payload);
233 ✗ burst_write_buf[0] = (LORA_REG_FIFO_RW | 0x80); /* set up reg write */
234 ✗ memcpy(&(burst_write_buf[1]), &payload, TELEMETRY_MESSAGE_SIZE);
235 ✗ lora_status = lora_write_IT(burst_write_buf, TELEMETRY_MESSAGE_SIZE + 1);
236 ✗ return;
237 }
238
239 ✗ case LORA_TX_STATE_WRITING_MSG: /* writing the message itself */
240 {
241 ✗ if( update_cause != LORA_FSM_EVENT_WRITE_CPLT )
242 {
243 /* do nothing */
244 return;
245 }
246
247 /* check status register */
248 ✗ tx_fsm = LORA_TX_STATE_PRE_TX_STATUS_CHECK;
249 ✗ lora_status = lora_read_register_IT(LORA_REG_OPERATION_MODE, register_contents);
250 ✗ return;
251 }
252
253 ✗ case LORA_TX_STATE_PRE_TX_STATUS_CHECK: /* writing the message itself */
254 {
255 ✗ if( update_cause != LORA_FSM_EVENT_REG_READ_CPLT )
256 {
257 /* do nothing */
258 return;
259 }
260
261 /* switch to TX mode */
262 ✗ tx_fsm = LORA_TX_STATE_STARTING_TRANSMISSION;
263 ✗ uint8_t new_opmode_register = (register_contents[1] & ~(0x7));
264 ✗ new_opmode_register = (new_opmode_register | LORA_TRANSMIT_MODE);
265 ✗ lora_status = lora_write_register_IT( LORA_REG_OPERATION_MODE, new_opmode_register );
266 ✗ return;
267 }
268
269 ✗ case LORA_TX_STATE_STARTING_TRANSMISSION:
270 {
271 ✗ if( update_cause != LORA_FSM_EVENT_WRITE_CPLT )
272 {
273 /* do nothing */
274 return;
275 }
276
277 /* opmode change complete, we are now transmitting */
278 ✗ tx_fsm = LORA_TX_STATE_TRANSMITTING;
279 ✗ register_contents[1] = 0xFF; /* set this to FF so we can detect when the contents have changed */
280 ✗ lora_status = lora_read_register_IT(LORA_REG_OPERATION_MODE, register_contents);
281 ✗ return;
282 }
283
284 ✗ case LORA_TX_STATE_TRANSMITTING:
285 {
286 ✗ if( ( update_cause != LORA_FSM_EVENT_EXTI_RAISED )
287 ✗ && ( update_cause != LORA_FSM_EVENT_REG_READ_CPLT ) )
288 {
289 /* do nothing */
290 return;
291 }
292
293 ✗ if( (register_contents[1] & 0b111) == LORA_STANDBY_MODE )
294 {
295 /* transmission is complete! start the buffer retrieval operation and jump higher on the FSM */
296 ✗ tx_fsm = LORA_TX_STATE_GETTING_BUF;
297 ✗ lora_status = lora_read_register_IT(LORA_REG_FIFO_TX_BASE_ADDR, register_contents);
298 }
299 else
300 {
301 ✗ lora_status = lora_read_register_IT(LORA_REG_OPERATION_MODE, register_contents);
302 }
303 return;
304 }
305
306 }
307
308
309 } /* lora_tx_update */
310