GCC Code Coverage Report


Directory: ../../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 86.1% 68 / 0 / 79
Functions: 100.0% 3 / 0 / 3
Branches: 73.9% 34 / 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 3473 void lora_fsm_update
78 (
79 LORA_FSM_EVENT update_cause
80 )
81 {
82
2/2
✓ Branch 0 taken 3472 times.
✓ Branch 1 taken 1 time.
3473 switch ( op_mode )
83 {
84 3472 case LORA_ASYNC_TX:
85 3472 lora_tx_update( update_cause );
86 3472 return;
87 default: /* any unhandled mode -- just return */
88 return;
89 }
90
91 } /* lora_fsm_update */
92
93
94 1 LORA_STATUS lora_fsm_set_mode
95 (
96 LORA_ASYNC_OP_MODE new_mode
97 )
98 {
99 /* Starting TX */
100
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if( ( new_mode == LORA_ASYNC_TX )
101
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 && ( op_mode == LORA_ASYNC_OFF ) )
102 {
103 1 op_mode = LORA_ASYNC_TX;
104 1 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 1 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 3472 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
1/2
✓ Branch 0 taken 3472 times.
✗ Branch 1 not taken.
3472 if( ( lora_status & ( LORA_FAIL | LORA_TRANSMIT_FAIL | LORA_TIMEOUT_FAIL ) )
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3472 times.
3472 || ( 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
9/10
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 497 times.
✓ Branch 3 taken 496 times.
✓ Branch 4 taken 497 times.
✓ Branch 5 taken 495 times.
✓ Branch 6 taken 495 times.
✓ Branch 7 taken 495 times.
✓ Branch 8 taken 494 times.
✗ Branch 9 not taken.
3472 switch( tx_fsm )
155 {
156 2 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
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 if( update_cause != LORA_FSM_EVENT_SYNCHRONOUS_UPDATE )
161 {
162 /* do nothing */
163 return;
164 }
165 1 tx_fsm = LORA_TX_STATE_STATUS_CHECK;
166 1 lora_status = lora_read_register_IT(LORA_REG_OPERATION_MODE, register_contents);
167 1 return;
168 }
169
170 1 case LORA_TX_STATE_STATUS_CHECK: /* check if in standby mode */
171 {
172
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 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 1 tx_fsm = LORA_TX_STATE_GETTING_BUF;
192 1 lora_status = lora_read_register_IT(LORA_REG_FIFO_TX_BASE_ADDR, register_contents);
193 }
194 1 return;
195 }
196
197 497 case LORA_TX_STATE_GETTING_BUF: /* get fifo base ptr */
198 {
199
2/2
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 166 times.
497 if( update_cause != LORA_FSM_EVENT_REG_READ_CPLT )
200 {
201 /* do nothing */
202 return;
203 }
204
205 331 tx_fsm = LORA_TX_STATE_SETTING_TX_BASE;
206 331 lora_status = lora_write_register_IT(LORA_REG_FIFO_SPI_POINTER, register_contents[1]);
207 331 return;
208 }
209
210 496 case LORA_TX_STATE_SETTING_TX_BASE: /* set tx base ptr */
211 {
212
2/2
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 165 times.
496 if( update_cause != LORA_FSM_EVENT_WRITE_CPLT )
213 {
214 /* do nothing */
215 return;
216 }
217
218 331 tx_fsm = LORA_TX_STATE_WRITING_MSG_LEN;
219 331 lora_status = lora_write_register_IT(LORA_REG_SIGNAL_TO_NOISE, TELEMETRY_MESSAGE_SIZE);
220 331 return;
221 }
222
223 497 case LORA_TX_STATE_WRITING_MSG_LEN: /* write the length of the lora message */
224 {
225
2/2
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 166 times.
497 if( update_cause != LORA_FSM_EVENT_WRITE_CPLT )
226 {
227 /* do nothing */
228 return;
229 }
230
231 331 tx_fsm = LORA_TX_STATE_WRITING_MSG;
232 331 telemetry_get_next_message(&payload);
233 331 burst_write_buf[0] = (LORA_REG_FIFO_RW | 0x80); /* set up reg write */
234 331 memcpy(&(burst_write_buf[1]), &payload, TELEMETRY_MESSAGE_SIZE);
235 331 lora_status = lora_write_IT(burst_write_buf, TELEMETRY_MESSAGE_SIZE + 1);
236 331 return;
237 }
238
239 495 case LORA_TX_STATE_WRITING_MSG: /* writing the message itself */
240 {
241
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 165 times.
495 if( update_cause != LORA_FSM_EVENT_WRITE_CPLT )
242 {
243 /* do nothing */
244 return;
245 }
246
247 /* check status register */
248 330 tx_fsm = LORA_TX_STATE_PRE_TX_STATUS_CHECK;
249 330 lora_status = lora_read_register_IT(LORA_REG_OPERATION_MODE, register_contents);
250 330 return;
251 }
252
253 495 case LORA_TX_STATE_PRE_TX_STATUS_CHECK: /* writing the message itself */
254 {
255
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 165 times.
495 if( update_cause != LORA_FSM_EVENT_REG_READ_CPLT )
256 {
257 /* do nothing */
258 return;
259 }
260
261 /* switch to TX mode */
262 330 tx_fsm = LORA_TX_STATE_STARTING_TRANSMISSION;
263 330 uint8_t new_opmode_register = (register_contents[1] & ~(0x7));
264 330 new_opmode_register = (new_opmode_register | LORA_TRANSMIT_MODE);
265 330 lora_status = lora_write_register_IT( LORA_REG_OPERATION_MODE, new_opmode_register );
266 330 return;
267 }
268
269 495 case LORA_TX_STATE_STARTING_TRANSMISSION:
270 {
271
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 165 times.
495 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 330 tx_fsm = LORA_TX_STATE_TRANSMITTING;
279 330 register_contents[1] = 0xFF; /* set this to FF so we can detect when the contents have changed */
280 330 lora_status = lora_read_register_IT(LORA_REG_OPERATION_MODE, register_contents);
281 330 return;
282 }
283
284 494 case LORA_TX_STATE_TRANSMITTING:
285 {
286 494 if( ( update_cause != LORA_FSM_EVENT_EXTI_RAISED )
287
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 164 times.
494 && ( update_cause != LORA_FSM_EVENT_REG_READ_CPLT ) )
288 {
289 /* do nothing */
290 return;
291 }
292
293
1/2
✓ Branch 0 taken 330 times.
✗ Branch 1 not taken.
330 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 330 tx_fsm = LORA_TX_STATE_GETTING_BUF;
297 330 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