driver/lora/lora.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /******************************************************************************* | ||
| 2 | * | ||
| 3 | * FILE: | ||
| 4 | * lora.c | ||
| 5 | * | ||
| 6 | * DESCRIPTION: | ||
| 7 | * Contains API functions for transmating and receiving from the board's | ||
| 8 | * built-in LoRa module. | ||
| 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 Inlcudes | ||
| 45 | ------------------------------------------------------------------------------*/ | ||
| 46 | #include "lora.h" | ||
| 47 | #include "usb.h" | ||
| 48 | #include "main.h" | ||
| 49 | |||
| 50 | /*------------------------------------------------------------------------------ | ||
| 51 | Global Variables | ||
| 52 | ------------------------------------------------------------------------------*/ | ||
| 53 | static LORA_STATUS lora_rx_done = LORA_WAITING; | ||
| 54 | static bool is_lora_configured = false; | ||
| 55 | |||
| 56 | /*------------------------------------------------------------------------------ | ||
| 57 | Internal function prototypes | ||
| 58 | ------------------------------------------------------------------------------*/ | ||
| 59 | /******************************************************************************* | ||
| 60 | * * | ||
| 61 | * PROCEDURE: * | ||
| 62 | * LORA_SPI_Receive * | ||
| 63 | * * | ||
| 64 | * DESCRIPTION: * | ||
| 65 | * Wrapper function for HAL SPI transmit * | ||
| 66 | * * | ||
| 67 | *******************************************************************************/ | ||
| 68 | 12 | static LORA_STATUS LORA_SPI_Receive | |
| 69 | ( | ||
| 70 | uint8_t* read_buffer_ptr | ||
| 71 | ) | ||
| 72 | { | ||
| 73 | /*------------------------------------------------------------------------------ | ||
| 74 | Local variables | ||
| 75 | ------------------------------------------------------------------------------*/ | ||
| 76 | 12 | HAL_StatusTypeDef status; | |
| 77 | |||
| 78 | /*------------------------------------------------------------------------------ | ||
| 79 | Implementation | ||
| 80 | ------------------------------------------------------------------------------*/ | ||
| 81 | |||
| 82 | /* Takes pointer to the read buffer. and puts output there */ | ||
| 83 | 12 | status = HAL_SPI_Receive( &(LORA_SPI), read_buffer_ptr, 1, LORA_TIMEOUT ); | |
| 84 | |||
| 85 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | if ( status == HAL_OK ) |
| 86 | { | ||
| 87 | /* Successful initializaiton */ | ||
| 88 | 12 | return LORA_OK; | |
| 89 | } | ||
| 90 | |||
| 91 | /* Failed initialization */ | ||
| 92 | return LORA_FAIL; | ||
| 93 | } | ||
| 94 | |||
| 95 | 12 | static LORA_STATUS LORA_SPI_Transmit_Byte | |
| 96 | ( | ||
| 97 | uint8_t byte | ||
| 98 | ) | ||
| 99 | { | ||
| 100 | /*------------------------------------------------------------------------------ | ||
| 101 | Local Variables | ||
| 102 | ------------------------------------------------------------------------------*/ | ||
| 103 | 12 | HAL_StatusTypeDef status; | |
| 104 | |||
| 105 | /*------------------------------------------------------------------------------ | ||
| 106 | Implementation | ||
| 107 | ------------------------------------------------------------------------------*/ | ||
| 108 | /* Takes register and data to write (1 byte) and writes that register. */ | ||
| 109 | 12 | status = HAL_SPI_Transmit( &(LORA_SPI), &byte, 1, LORA_TIMEOUT); | |
| 110 | |||
| 111 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | if (status == HAL_OK) |
| 112 | { | ||
| 113 | /* SPI transmpit successful */ | ||
| 114 | 12 | return LORA_OK; | |
| 115 | } | ||
| 116 | |||
| 117 | return LORA_FAIL; | ||
| 118 | } | ||
| 119 | |||
| 120 | /******************************************************************************* | ||
| 121 | * * | ||
| 122 | * PROCEDURE: * | ||
| 123 | * LORA_SPI_Transmit_Data * | ||
| 124 | * * | ||
| 125 | * DESCRIPTION: * | ||
| 126 | * Transmit data over SPI * | ||
| 127 | * * | ||
| 128 | *******************************************************************************/ | ||
| 129 | 18 | static LORA_STATUS LORA_SPI_Transmit_Data | |
| 130 | ( | ||
| 131 | LORA_REGISTER_ADDR reg, | ||
| 132 | uint8_t data | ||
| 133 | ) | ||
| 134 | { | ||
| 135 | 18 | HAL_StatusTypeDef status; | |
| 136 | |||
| 137 | /* Takes register and data to write and writes that register. */ | ||
| 138 | 18 | uint8_t transmitBuffer[2] = { reg, data }; | |
| 139 | 18 | status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer[0], 2, LORA_TIMEOUT); | |
| 140 | |||
| 141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | if (status == HAL_OK){ |
| 142 | return LORA_OK; | ||
| 143 | ✗ | } else return LORA_FAIL; | |
| 144 | } | ||
| 145 | |||
| 146 | /******************************************************************************* | ||
| 147 | * * | ||
| 148 | * PROCEDURE: * | ||
| 149 | * lora_read_register * | ||
| 150 | * * | ||
| 151 | * DESCRIPTION: * | ||
| 152 | * Read internal modem register * | ||
| 153 | * * | ||
| 154 | *******************************************************************************/ | ||
| 155 | 12 | static LORA_STATUS lora_read_register | |
| 156 | ( | ||
| 157 | LORA_REGISTER_ADDR lora_register, | ||
| 158 | uint8_t* pRegData | ||
| 159 | ) | ||
| 160 | { | ||
| 161 | 12 | LORA_STATUS transmit_status, receive_status; | |
| 162 | |||
| 163 | 12 | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); | |
| 164 | |||
| 165 | 12 | transmit_status = LORA_SPI_Transmit_Byte( (lora_register & 0x7F) ); | |
| 166 | 12 | receive_status = LORA_SPI_Receive( pRegData ); | |
| 167 | |||
| 168 | 12 | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); | |
| 169 | |||
| 170 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (transmit_status + receive_status == 0){ |
| 171 | return LORA_OK; | ||
| 172 | } else { | ||
| 173 | ✗ | return LORA_FAIL; | |
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | /******************************************************************************* | ||
| 178 | * * | ||
| 179 | * PROCEDURE: * | ||
| 180 | * lora_read_register_buffer * | ||
| 181 | * * | ||
| 182 | * DESCRIPTION: * | ||
| 183 | * Read buffer from internal modem register * | ||
| 184 | * * | ||
| 185 | *******************************************************************************/ | ||
| 186 | ✗ | static LORA_STATUS lora_read_register_buffer | |
| 187 | ( | ||
| 188 | LORA_REGISTER_ADDR lora_register, | ||
| 189 | uint8_t* pRegData, | ||
| 190 | uint8_t buffer_len | ||
| 191 | ) | ||
| 192 | { | ||
| 193 | ✗ | LORA_STATUS status; | |
| 194 | ✗ | HAL_StatusTypeDef hal_status; | |
| 195 | |||
| 196 | ✗ | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); | |
| 197 | |||
| 198 | ✗ | status = LORA_SPI_Transmit_Byte( (lora_register & 0x7F) ); | |
| 199 | ✗ | if( status != LORA_OK ) | |
| 200 | return LORA_FAIL; | ||
| 201 | |||
| 202 | ✗ | hal_status = HAL_SPI_Receive( &(LORA_SPI), pRegData, buffer_len, LORA_TIMEOUT ); | |
| 203 | ✗ | if( hal_status != HAL_OK ) | |
| 204 | return LORA_FAIL; | ||
| 205 | |||
| 206 | ✗ | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); | |
| 207 | |||
| 208 | ✗ | return LORA_OK; | |
| 209 | } | ||
| 210 | |||
| 211 | /******************************************************************************* | ||
| 212 | * * | ||
| 213 | * PROCEDURE: * | ||
| 214 | * lora_write_register * | ||
| 215 | * * | ||
| 216 | * DESCRIPTION: * | ||
| 217 | * Write internal modem register * | ||
| 218 | * * | ||
| 219 | *******************************************************************************/ | ||
| 220 | 18 | static LORA_STATUS lora_write_register | |
| 221 | ( | ||
| 222 | LORA_REGISTER_ADDR lora_register, | ||
| 223 | uint8_t data | ||
| 224 | ) | ||
| 225 | { | ||
| 226 | 18 | LORA_STATUS status; | |
| 227 | |||
| 228 | 18 | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); | |
| 229 | |||
| 230 | 18 | status = LORA_SPI_Transmit_Data( (lora_register | 0x80), data ); | |
| 231 | |||
| 232 | 18 | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); | |
| 233 | |||
| 234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | if ( status == LORA_OK ) |
| 235 | return LORA_OK; | ||
| 236 | ✗ | else return LORA_FAIL; | |
| 237 | } | ||
| 238 | |||
| 239 | /******************************************************************************* | ||
| 240 | * * | ||
| 241 | * PROCEDURE: * | ||
| 242 | * lora_write_register_buffer * | ||
| 243 | * * | ||
| 244 | * DESCRIPTION: * | ||
| 245 | * Write internal modem register with data buffer * | ||
| 246 | * * | ||
| 247 | *******************************************************************************/ | ||
| 248 | ✗ | static LORA_STATUS lora_write_register_buffer | |
| 249 | ( | ||
| 250 | LORA_REGISTER_ADDR lora_register, | ||
| 251 | uint8_t* data, | ||
| 252 | uint8_t buffer_len | ||
| 253 | ) | ||
| 254 | { | ||
| 255 | ✗ | HAL_StatusTypeDef status; | |
| 256 | |||
| 257 | ✗ | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); | |
| 258 | |||
| 259 | // SPI write regester we are writing | ||
| 260 | ✗ | uint8_t dest_reg = (lora_register | 0x80); | |
| 261 | ✗ | status = HAL_SPI_Transmit( &(LORA_SPI), &dest_reg, 1, LORA_TIMEOUT); | |
| 262 | ✗ | if ( status != HAL_OK ) | |
| 263 | return LORA_FAIL; | ||
| 264 | |||
| 265 | // Write desire buffer | ||
| 266 | ✗ | status = HAL_SPI_Transmit( &(LORA_SPI), data, buffer_len, LORA_TIMEOUT); | |
| 267 | ✗ | if ( status != HAL_OK ) | |
| 268 | return LORA_FAIL; | ||
| 269 | |||
| 270 | ✗ | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); | |
| 271 | |||
| 272 | |||
| 273 | ✗ | return LORA_OK; | |
| 274 | } | ||
| 275 | |||
| 276 | |||
| 277 | /******************************************************************************* | ||
| 278 | * * | ||
| 279 | * PROCEDURE: * | ||
| 280 | * lora_is_lora_initialized * | ||
| 281 | * * | ||
| 282 | * DESCRIPTION: * | ||
| 283 | * Determine initialization state of LoRa modem. * | ||
| 284 | * * | ||
| 285 | *******************************************************************************/ | ||
| 286 | 1 | bool lora_is_lora_initialized | |
| 287 | ( | ||
| 288 | void | ||
| 289 | ) | ||
| 290 | { | ||
| 291 | 1 | return is_lora_configured; | |
| 292 | |||
| 293 | } /* lora_is_lora_initialized */ | ||
| 294 | |||
| 295 | |||
| 296 | /******************************************************************************* | ||
| 297 | * * | ||
| 298 | * PROCEDURE: * | ||
| 299 | * lora_cmd_execute * | ||
| 300 | * * | ||
| 301 | * DESCRIPTION: * | ||
| 302 | * Execute a LoRa terminal command. * | ||
| 303 | * * | ||
| 304 | *******************************************************************************/ | ||
| 305 | 1 | LORA_STATUS lora_cmd_execute | |
| 306 | ( | ||
| 307 | uint8_t subcommand_code, | ||
| 308 | LORA_PRESET* lora_preset_buf | ||
| 309 | ) | ||
| 310 | { | ||
| 311 |
1/3✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
1 | switch (subcommand_code) |
| 312 | { | ||
| 313 | /*------------------------------------------------------------- | ||
| 314 | Upload Preset (to FC) | ||
| 315 | -------------------------------------------------------------*/ | ||
| 316 | 1 | case LORA_PRESET_UPLOAD: | |
| 317 | { | ||
| 318 | /* Recieve preset subcommand over USB */ | ||
| 319 | 1 | uint8_t data_receive_buffer[sizeof( LORA_PRESET )]; | |
| 320 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | if (usb_receive( data_receive_buffer, |
| 321 | sizeof( LORA_PRESET ), | ||
| 322 | 10 * HAL_DEFAULT_TIMEOUT ) == USB_OK) | ||
| 323 | { | ||
| 324 | /* Copy received data into preset data */ | ||
| 325 | 1 | memcpy(lora_preset_buf, data_receive_buffer, sizeof( LORA_PRESET ) ); | |
| 326 | 1 | return LORA_OK; | |
| 327 | } | ||
| 328 | else | ||
| 329 | { | ||
| 330 | /* lora presets remain untouched if usb receive fails */ | ||
| 331 | return LORA_FAIL; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | /*------------------------------------------------------------- | ||
| 335 | Download Preset (from FC) | ||
| 336 | -------------------------------------------------------------*/ | ||
| 337 | ✗ | case LORA_PRESET_DOWNLOAD: | |
| 338 | { | ||
| 339 | /* tx straight from buffer (usb transmit does not modify the buffer) */ | ||
| 340 | ✗ | if( usb_transmit( lora_preset_buf, sizeof( LORA_PRESET ), 10 * HAL_DEFAULT_TIMEOUT ) == USB_OK ) | |
| 341 | { | ||
| 342 | return LORA_OK; | ||
| 343 | } | ||
| 344 | else | ||
| 345 | { | ||
| 346 | ✗ | return LORA_FAIL; | |
| 347 | } | ||
| 348 | } | ||
| 349 | /*------------------------------------------------------------- | ||
| 350 | Unrecognized command code | ||
| 351 | -------------------------------------------------------------*/ | ||
| 352 | default: | ||
| 353 | { | ||
| 354 | return LORA_FAIL; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 358 | } /* lora_cmd_execute */ | ||
| 359 | |||
| 360 | |||
| 361 | /******************************************************************************* | ||
| 362 | * * | ||
| 363 | * PROCEDURE: * | ||
| 364 | * lora_configure * | ||
| 365 | * * | ||
| 366 | * DESCRIPTION: * | ||
| 367 | * Configure and re-initialize the lora modem. * | ||
| 368 | * * | ||
| 369 | *******************************************************************************/ | ||
| 370 | 2 | LORA_STATUS lora_configure | |
| 371 | ( | ||
| 372 | LORA_PRESET* preset | ||
| 373 | ) | ||
| 374 | { | ||
| 375 | 2 | LORA_CONFIG lora_config; | |
| 376 | 2 | LORA_STATUS lora_status = LORA_OK; | |
| 377 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | memset( &lora_config, 0, sizeof( lora_config ) ); |
| 378 | |||
| 379 | /* Set app-dependent (non-configurable) parameters. */ | ||
| 380 | // ETS TEMP: We may elect to change these later, but this | ||
| 381 | // is what we're using for now. | ||
| 382 | 2 | lora_config.lora_header_mode = LORA_EXPLICIT_HEADER; | |
| 383 | 2 | lora_config.lora_mode = LORA_STANDBY_MODE; | |
| 384 | |||
| 385 | /* Make sure presets are neither all 0xFF nor all 0x00 for validity */ | ||
| 386 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if( preset ) |
| 387 | { | ||
| 388 | /* 00 buffer check */ | ||
| 389 | 2 | uint8_t cmp_buf[sizeof(LORA_PRESET)]; | |
| 390 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | memset(cmp_buf, 0x00, sizeof(LORA_PRESET)); |
| 391 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!memcmp(cmp_buf, preset, sizeof(LORA_PRESET))) |
| 392 | { | ||
| 393 | ✗ | preset = NULL; | |
| 394 | } | ||
| 395 | |||
| 396 | /* FF buffer check */ | ||
| 397 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | memset(cmp_buf, 0xFF, sizeof(LORA_PRESET)); |
| 398 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (preset && !memcmp(cmp_buf, preset, sizeof(LORA_PRESET))) |
| 399 | { | ||
| 400 | ✗ | preset = NULL; | |
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | /* Check if presets exist. If so, we'll use them. Else, prepare defaults. */ | ||
| 405 | ✗ | if( !preset ) | |
| 406 | { | ||
| 407 | /* drew's most frequently tested parameters. in particular, 915 will help us see that these are the defaults */ | ||
| 408 | ✗ | lora_config.lora_bandwidth = LORA_BANDWIDTH_125_KHZ; | |
| 409 | ✗ | lora_config.lora_ecr = LORA_ECR_4_5; | |
| 410 | ✗ | lora_config.lora_frequency = 915000; | |
| 411 | ✗ | lora_config.lora_spread = LORA_SPREAD_12; | |
| 412 | ✗ | lora_config.lora_pa_select = false; | |
| 413 | |||
| 414 | ✗ | lora_status = LORA_USING_DEFAULTS; | |
| 415 | } | ||
| 416 | else | ||
| 417 | { | ||
| 418 | 2 | lora_config.lora_bandwidth = preset->lora_bandwidth; | |
| 419 | 2 | lora_config.lora_ecr = preset->lora_ecr - 4; | |
| 420 | 2 | lora_config.lora_frequency = preset->lora_frequency; | |
| 421 | 2 | lora_config.lora_spread = preset->lora_spread; | |
| 422 | 2 | lora_config.lora_pa_select = preset->high_power_mode; | |
| 423 | |||
| 424 | 2 | lora_status = LORA_OK; | |
| 425 | } | ||
| 426 | |||
| 427 | /* reset and re-initialize */ | ||
| 428 | 2 | lora_reset(); | |
| 429 | 2 | HAL_Delay(10); | |
| 430 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if (lora_init( &lora_config ) == LORA_OK) |
| 431 | { | ||
| 432 | 2 | is_lora_configured = true; | |
| 433 | 2 | return lora_status; | |
| 434 | } | ||
| 435 | else | ||
| 436 | { | ||
| 437 | return LORA_FAIL; | ||
| 438 | } | ||
| 439 | |||
| 440 | } /* lora_configure */ | ||
| 441 | |||
| 442 | // Get the device chip ID | ||
| 443 | 2 | static LORA_STATUS lora_get_device_id | |
| 444 | ( | ||
| 445 | uint8_t* buffer_ptr | ||
| 446 | ) | ||
| 447 | { | ||
| 448 | 2 | LORA_STATUS status; | |
| 449 | |||
| 450 | 2 | status = lora_read_register( LORA_REG_ID_VERSION, buffer_ptr ); | |
| 451 | |||
| 452 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if ( status == LORA_OK ) |
| 453 | return LORA_OK; | ||
| 454 | ✗ | else return LORA_FAIL; | |
| 455 | } | ||
| 456 | |||
| 457 | |||
| 458 | /*------------------------------------------------------------------------------ | ||
| 459 | Procedures | ||
| 460 | ------------------------------------------------------------------------------*/ | ||
| 461 | |||
| 462 | /******************************************************************************* | ||
| 463 | * * | ||
| 464 | * PROCEDURE: * | ||
| 465 | * lora_read_register_IT * | ||
| 466 | * * | ||
| 467 | * DESCRIPTION: * | ||
| 468 | * Read internal modem register. * | ||
| 469 | * * | ||
| 470 | * NOTE: * | ||
| 471 | * A completion callback (HAL_SPI_TxRxCpltCallback) for this operation * | ||
| 472 | * MUST be registered for the LoRa SPI handle. The completion callback * | ||
| 473 | * must pull NSS high like so: * | ||
| 474 | * * | ||
| 475 | * HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); * | ||
| 476 | * * | ||
| 477 | *******************************************************************************/ | ||
| 478 | 992 | LORA_STATUS lora_read_register_IT | |
| 479 | ( | ||
| 480 | uint8_t lora_register, | ||
| 481 | uint8_t* pRegData /* o: 2 byte array; first byte will be empty, second will have the data */ | ||
| 482 | ) | ||
| 483 | { | ||
| 484 | 992 | HAL_StatusTypeDef hal_status; | |
| 485 | 992 | static uint8_t read_reg[2]; | |
| 486 | 992 | read_reg[0] = lora_register & 0x7F; | |
| 487 | 992 | read_reg[1] = 0x00; | |
| 488 | |||
| 489 | 992 | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); | |
| 490 | 992 | hal_status = HAL_SPI_TransmitReceive_IT( &(LORA_SPI), read_reg, pRegData, 2 ); | |
| 491 | |||
| 492 | /* NSS high is in the callback */ | ||
| 493 | |||
| 494 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 992 times.
|
992 | if ( hal_status == HAL_OK ) |
| 495 | { | ||
| 496 | return LORA_OK; | ||
| 497 | } | ||
| 498 | else | ||
| 499 | { | ||
| 500 | ✗ | return LORA_FAIL; | |
| 501 | } | ||
| 502 | |||
| 503 | } /* lora_read_register_IT */ | ||
| 504 | |||
| 505 | |||
| 506 | /******************************************************************************* | ||
| 507 | * * | ||
| 508 | * PROCEDURE: * | ||
| 509 | * lora_write_register_IT * | ||
| 510 | * * | ||
| 511 | * DESCRIPTION: * | ||
| 512 | * Write to modem (register write). * | ||
| 513 | * * | ||
| 514 | * NOTE: * | ||
| 515 | * A completion callback (HAL_SPI_TxCpltCallback) for this operation * | ||
| 516 | * MUST be registered for the LoRa SPI handle. The completion callback * | ||
| 517 | * must pull NSS high like so: * | ||
| 518 | * * | ||
| 519 | * HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); * | ||
| 520 | * * | ||
| 521 | *******************************************************************************/ | ||
| 522 | 992 | LORA_STATUS lora_write_register_IT | |
| 523 | ( | ||
| 524 | uint8_t lora_register, | ||
| 525 | uint8_t data | ||
| 526 | ) | ||
| 527 | { | ||
| 528 | 992 | static uint8_t write_reg[2]; /* statically scoped so it doesn't go out of scope during tx */ | |
| 529 | 992 | write_reg[0] = (lora_register | 0x80); | |
| 530 | 992 | write_reg[1] = data; | |
| 531 | |||
| 532 | 992 | return lora_write_IT(write_reg, 2); | |
| 533 | |||
| 534 | } /* lora_write_register_IT */ | ||
| 535 | |||
| 536 | |||
| 537 | /******************************************************************************* | ||
| 538 | * * | ||
| 539 | * PROCEDURE: * | ||
| 540 | * lora_write_IT * | ||
| 541 | * * | ||
| 542 | * DESCRIPTION: * | ||
| 543 | * Write to modem (burst write, also used for register write). * | ||
| 544 | * * | ||
| 545 | * NOTE: * | ||
| 546 | * A completion callback (HAL_SPI_TxCpltCallback) for this operation * | ||
| 547 | * MUST be registered for the LoRa SPI handle. The completion callback * | ||
| 548 | * must pull NSS high like so: * | ||
| 549 | * * | ||
| 550 | * HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); * | ||
| 551 | * * | ||
| 552 | *******************************************************************************/ | ||
| 553 | 1323 | LORA_STATUS lora_write_IT | |
| 554 | ( | ||
| 555 | uint8_t* data, | ||
| 556 | size_t len | ||
| 557 | ) | ||
| 558 | { | ||
| 559 | 1323 | HAL_StatusTypeDef hal_status; | |
| 560 | |||
| 561 | 1323 | HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); | |
| 562 | 1323 | hal_status = HAL_SPI_Transmit_IT( &(LORA_SPI), data, len ); | |
| 563 | |||
| 564 | /* NSS high is in the callback */ | ||
| 565 | |||
| 566 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1323 times.
|
1323 | if ( hal_status == HAL_OK ) |
| 567 | { | ||
| 568 | return LORA_OK; | ||
| 569 | } | ||
| 570 | else | ||
| 571 | { | ||
| 572 | ✗ | return LORA_FAIL; | |
| 573 | } | ||
| 574 | |||
| 575 | } /* lora_write_IT */ | ||
| 576 | |||
| 577 | |||
| 578 | /******************************************************************************* | ||
| 579 | * * | ||
| 580 | * PROCEDURE: * | ||
| 581 | * lora_set_chip_mode * | ||
| 582 | * * | ||
| 583 | * DESCRIPTION: * | ||
| 584 | * Set operation mode of LoRa modem * | ||
| 585 | * * | ||
| 586 | *******************************************************************************/ | ||
| 587 | 4 | LORA_STATUS lora_set_chip_mode | |
| 588 | ( | ||
| 589 | LORA_CHIPMODE chip_mode | ||
| 590 | ) | ||
| 591 | { | ||
| 592 | // Get initial value of the operation mode register | ||
| 593 | 4 | uint8_t operation_mode_register; | |
| 594 | 4 | LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); | |
| 595 | |||
| 596 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (read_status != LORA_OK) |
| 597 | { | ||
| 598 | return LORA_FAIL; | ||
| 599 | } | ||
| 600 | |||
| 601 | // // Fail if not in LORA Mode | ||
| 602 | // if ( !( operation_mode_register & (1<<7) ) ){ | ||
| 603 | // return LORA_FAIL; | ||
| 604 | // } | ||
| 605 | |||
| 606 | // Change the value of the chip register to set it to the suggested chip mode | ||
| 607 | 4 | uint8_t new_opmode_register = (operation_mode_register & ~(0x7)); | |
| 608 | 4 | new_opmode_register = (new_opmode_register | chip_mode); | |
| 609 | |||
| 610 | // Write new byte | ||
| 611 | 4 | LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); | |
| 612 | |||
| 613 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if ( write_status + read_status == 0 ){ |
| 614 | return LORA_OK; | ||
| 615 | } else { | ||
| 616 | ✗ | return LORA_FAIL; | |
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | /******************************************************************************* | ||
| 621 | * * | ||
| 622 | * PROCEDURE: * | ||
| 623 | * lora_init * | ||
| 624 | * * | ||
| 625 | * DESCRIPTION: * | ||
| 626 | * Initialize LoRa modem * | ||
| 627 | * * | ||
| 628 | *******************************************************************************/ | ||
| 629 | 2 | LORA_STATUS lora_init | |
| 630 | ( | ||
| 631 | LORA_CONFIG *lora_config_ptr | ||
| 632 | ) | ||
| 633 | { | ||
| 634 | // TODO add check for accurate chip ID (more than zero) | ||
| 635 | 2 | uint8_t device_id = 0; | |
| 636 | 2 | lora_get_device_id( &device_id ); | |
| 637 | |||
| 638 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if( device_id != 0x12 ) { |
| 639 | return LORA_FAIL; | ||
| 640 | } | ||
| 641 | |||
| 642 | // Check legality of frequency settings | ||
| 643 | // We do this first so that nothing gets set if we're on an illegal frequency. | ||
| 644 | |||
| 645 | // Get a version of our bandwidth for legality calculations | ||
| 646 | 2 | uint32_t bandwidth; // Calculations down in hz due to decimal bandwidths | |
| 647 |
1/11✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
2 | switch( lora_config_ptr->lora_bandwidth ) { |
| 648 | case LORA_BANDWIDTH_7_8_KHZ: | ||
| 649 | bandwidth = 7800; | ||
| 650 | break; | ||
| 651 | ✗ | case LORA_BANDWIDTH_10_4_KHZ: | |
| 652 | ✗ | bandwidth = 10400; | |
| 653 | ✗ | break; | |
| 654 | ✗ | case LORA_BANDWIDTH_15_6_KHZ: | |
| 655 | ✗ | bandwidth = 15600; | |
| 656 | ✗ | break; | |
| 657 | ✗ | case LORA_BANDWIDTH_20_8_KHZ: | |
| 658 | ✗ | bandwidth = 20800; | |
| 659 | ✗ | break; | |
| 660 | ✗ | case LORA_BANDWIDTH_31_25_KHZ: | |
| 661 | ✗ | bandwidth = 31250; | |
| 662 | ✗ | break; | |
| 663 | ✗ | case LORA_BANDWIDTH_41_7_KHZ: | |
| 664 | ✗ | bandwidth = 41700; | |
| 665 | ✗ | break; | |
| 666 | ✗ | case LORA_BANDWIDTH_62_5_KHZ: | |
| 667 | ✗ | bandwidth = 62500; | |
| 668 | ✗ | break; | |
| 669 | ✗ | case LORA_BANDWIDTH_125_KHZ: | |
| 670 | ✗ | bandwidth = 125000; | |
| 671 | ✗ | break; | |
| 672 | 2 | case LORA_BANDWIDTH_250_KHZ: | |
| 673 | 2 | bandwidth = 250000; | |
| 674 | 2 | break; | |
| 675 | ✗ | case LORA_BANDWIDTH_500_KHZ: | |
| 676 | ✗ | bandwidth = 500000; | |
| 677 | ✗ | break; | |
| 678 | default: | ||
| 679 | // Just in case, even though this is reading an enum | ||
| 680 | return LORA_FAIL; | ||
| 681 | } | ||
| 682 | |||
| 683 | // Check legal compliance of frequency: | ||
| 684 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if( !( lora_config_ptr->lora_frequency * 1000 + ( bandwidth / 2 ) <= ISM_MAX_FREQ * 1000 && |
| 685 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | lora_config_ptr->lora_frequency * 1000 - ( bandwidth / 2 ) >= ISM_MIN_FREQ * 1000 ) |
| 686 | ) { | ||
| 687 | return LORA_FAIL; | ||
| 688 | } | ||
| 689 | |||
| 690 | 2 | LORA_STATUS set_sleep_status = lora_set_chip_mode( LORA_SLEEP_MODE ); // Switch to sleep mode to enable LoRa bit (datasheeet page 102) | |
| 691 | // Get initial value of the operation mode register | ||
| 692 | 2 | uint8_t operation_mode_register; | |
| 693 | 2 | LORA_STATUS read_status1 = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); | |
| 694 | |||
| 695 | 2 | uint8_t new_opmode_register; | |
| 696 | 2 | new_opmode_register = ( operation_mode_register | 0b10000000 ); // Toggle the LoRa bit | |
| 697 | |||
| 698 | // Write new byte | ||
| 699 | 2 | LORA_STATUS write_status1 = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); | |
| 700 | |||
| 701 | // Get initial value of config register 2 | ||
| 702 | 2 | uint8_t modem_config2_register; | |
| 703 | 2 | LORA_STATUS read_status2 = lora_read_register( LORA_REG_RX_HEADER_INFO, &modem_config2_register ); | |
| 704 | |||
| 705 | 2 | uint8_t new_config2_register = modem_config2_register & 0x0F; // Erase spread factor bits | |
| 706 | 2 | new_config2_register = ( new_config2_register | ( lora_config_ptr->lora_spread << 4 ) ); // Set the spread factor | |
| 707 | 2 | LORA_STATUS write_status2 = lora_write_register( LORA_REG_RX_HEADER_INFO, new_config2_register ); // Write new spread factor | |
| 708 | |||
| 709 | // Get initial value of config register 1 | ||
| 710 | 2 | uint8_t modem_config1_register; | |
| 711 | 2 | LORA_STATUS read_status3 = lora_read_register( LORA_REG_NUM_RX_BYTES, &modem_config1_register ); | |
| 712 | 2 | uint8_t new_config1_register = ( (lora_config_ptr->lora_bandwidth << 4) | (lora_config_ptr->lora_ecr << 1) | lora_config_ptr->lora_header_mode ); //TODO: Check datasheet for that last bit | |
| 713 | |||
| 714 | // Write new config1 register | ||
| 715 | 2 | LORA_STATUS write_status3 = lora_write_register( LORA_REG_NUM_RX_BYTES, new_config1_register ); | |
| 716 | |||
| 717 | // Determine register values for the frequency registers | ||
| 718 | 2 | uint32_t freq_mhz = lora_config_ptr->lora_frequency / 1000; // The megahertz component of our frequency. | |
| 719 | 2 | uint32_t freq_khz = lora_config_ptr->lora_frequency - freq_mhz * 1000; // The kilohertz component of our frequency. | |
| 720 | // The formula for converting khz to chip unit is fruqency * 524288 / ( 32 * 1000 ) | ||
| 721 | // Straight up doing that causes an integer overflow, though, so I have to do it this way. | ||
| 722 | 2 | uint32_t frf_reg = ( freq_mhz * 524288 / 32 ) + ( freq_khz * 524288 / ( 32 * 1000 ) ); | |
| 723 | |||
| 724 | 2 | uint8_t lora_freq_reg1 = ( frf_reg << 8 ) >> 24; | |
| 725 | 2 | uint8_t lora_freq_reg2 = ( frf_reg << 16 ) >> 24; | |
| 726 | 2 | uint8_t lora_freq_reg3 = ( frf_reg << 24 ) >> 24; | |
| 727 | |||
| 728 | // Write the frequency registers | ||
| 729 | 2 | LORA_STATUS write_status4 = lora_write_register( LORA_REG_FREQ_MSB, lora_freq_reg1 ); | |
| 730 | 2 | LORA_STATUS write_status5 = lora_write_register( LORA_REG_FREQ_MSD, lora_freq_reg2 ); | |
| 731 | 2 | LORA_STATUS write_status6 = lora_write_register( LORA_REG_FREQ_LSB, lora_freq_reg3 ); | |
| 732 | |||
| 733 | // Determine register values for the PA Config Register | ||
| 734 | 2 | uint8_t new_pa_select_reg; | |
| 735 | |||
| 736 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if( lora_config_ptr->lora_pa_select ) |
| 737 | { | ||
| 738 | new_pa_select_reg = 0b11111111; /* PA select, everything else maxed out */ | ||
| 739 | } | ||
| 740 | else | ||
| 741 | { | ||
| 742 | ✗ | new_pa_select_reg = 0b01111111; /* RFO select, everything else maxed out */ | |
| 743 | } | ||
| 744 | |||
| 745 | // Write the PA Config Register | ||
| 746 | 2 | LORA_STATUS write_status7 = lora_write_register( LORA_REG_PA_CONFIG, new_pa_select_reg ); | |
| 747 | |||
| 748 | 2 | LORA_STATUS standby_status = lora_set_chip_mode( lora_config_ptr->lora_mode ); // Switch it into standby mode, which is what's convenient. | |
| 749 | |||
| 750 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if( set_sleep_status + read_status1 + read_status2 + read_status3 + write_status1 + write_status2 + write_status3 + write_status4 + write_status5 + write_status6 + write_status7 + standby_status == 0 ) { |
| 751 | return LORA_OK; | ||
| 752 | } else { | ||
| 753 | ✗ | return LORA_FAIL; | |
| 754 | } | ||
| 755 | } | ||
| 756 | |||
| 757 | /******************************************************************************* | ||
| 758 | * * | ||
| 759 | * PROCEDURE: * | ||
| 760 | * lora_reset * | ||
| 761 | * * | ||
| 762 | * DESCRIPTION: * | ||
| 763 | * Reset LoRa modem (Initialization function needs to be called again) * | ||
| 764 | * * | ||
| 765 | *******************************************************************************/ | ||
| 766 | 2 | void lora_reset | |
| 767 | ( | ||
| 768 | void | ||
| 769 | ) | ||
| 770 | { | ||
| 771 | 2 | HAL_GPIO_WritePin(LORA_RST_GPIO_PORT, LORA_RST_PIN, GPIO_PIN_RESET); // Pull Low | |
| 772 | 2 | HAL_Delay(10); // Hold reset low for 10 ms | |
| 773 | 2 | HAL_GPIO_WritePin(LORA_RST_GPIO_PORT, LORA_RST_PIN, GPIO_PIN_SET); // Pull High | |
| 774 | 2 | HAL_Delay(10); // Wait for SX1278 to stabilize | |
| 775 | 2 | } | |
| 776 | |||
| 777 | /******************************************************************************* | ||
| 778 | * * | ||
| 779 | * PROCEDURE: * | ||
| 780 | * lora_transmit * | ||
| 781 | * * | ||
| 782 | * DESCRIPTION: * | ||
| 783 | * transmit a buffer through lora fifo * | ||
| 784 | * * | ||
| 785 | *******************************************************************************/ | ||
| 786 | ✗ | LORA_STATUS lora_transmit | |
| 787 | ( | ||
| 788 | uint8_t* buffer_ptr, | ||
| 789 | uint8_t buffer_len | ||
| 790 | ) | ||
| 791 | { | ||
| 792 | // Mode request STAND-BY | ||
| 793 | ✗ | LORA_STATUS standby_status = lora_set_chip_mode(LORA_STANDBY_MODE); | |
| 794 | |||
| 795 | // Write data to LoRA FIFO | ||
| 796 | ✗ | uint8_t fifo_ptr_addr; | |
| 797 | ✗ | LORA_STATUS tx_base_status = lora_read_register(LORA_REG_FIFO_TX_BASE_ADDR, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer | |
| 798 | ✗ | if (tx_base_status + standby_status != LORA_OK){ | |
| 799 | // Error handler | ||
| 800 | // led_set_color(// led_RED); | ||
| 801 | return LORA_FAIL; | ||
| 802 | } | ||
| 803 | ✗ | LORA_STATUS ptr_status = lora_write_register(LORA_REG_FIFO_SPI_POINTER, fifo_ptr_addr); // Set fifo data pointer to TX base address | |
| 804 | ✗ | if (ptr_status != LORA_OK){ | |
| 805 | // Error handler | ||
| 806 | // led_set_color(// led_RED); | ||
| 807 | return LORA_FAIL; | ||
| 808 | } | ||
| 809 | |||
| 810 | // Write buffer length to fifo_rw | ||
| 811 | ✗ | LORA_STATUS fifo_status = lora_write_register(LORA_REG_SIGNAL_TO_NOISE, buffer_len); | |
| 812 | |||
| 813 | // Send byte to byte to the fifo buffer | ||
| 814 | ✗ | LORA_STATUS sendbyte_status = LORA_OK; | |
| 815 | |||
| 816 | /* | ||
| 817 | // Old transmit buffer write code | ||
| 818 | // TODO don't remove until burst transmit is working | ||
| 819 | for (int i = 0; i<buffer_len; i++){ | ||
| 820 | sendbyte_status = lora_write_register(LORA_REG_FIFO_RW, buffer_ptr[i]); | ||
| 821 | } | ||
| 822 | */ | ||
| 823 | |||
| 824 | ✗ | sendbyte_status = lora_write_register_buffer( LORA_REG_FIFO_RW, buffer_ptr, buffer_len ); | |
| 825 | |||
| 826 | ✗ | LORA_STATUS tmode_status = lora_set_chip_mode(LORA_TRANSMIT_MODE); | |
| 827 | |||
| 828 | ✗ | uint8_t lora_op; | |
| 829 | ✗ | LORA_STATUS regop_status; | |
| 830 | ✗ | while (1){ // TODO Add a timeout here | |
| 831 | ✗ | regop_status = lora_read_register(LORA_REG_OPERATION_MODE, &lora_op); | |
| 832 | ✗ | if ((lora_op & 0b111) == LORA_STANDBY_MODE){ | |
| 833 | break; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | ✗ | if( fifo_status + tmode_status + regop_status + sendbyte_status == 0 ) { | |
| 837 | return LORA_OK; | ||
| 838 | } else { | ||
| 839 | ✗ | return LORA_FAIL; | |
| 840 | } | ||
| 841 | } | ||
| 842 | |||
| 843 | /******************************************************************************* | ||
| 844 | * * | ||
| 845 | * PROCEDURE: * | ||
| 846 | * lora_receive_ready * | ||
| 847 | * * | ||
| 848 | * DESCRIPTION: * | ||
| 849 | * Check if new packt has been received * | ||
| 850 | * * | ||
| 851 | *******************************************************************************/ | ||
| 852 | ✗ | LORA_STATUS lora_receive_ready | |
| 853 | ( | ||
| 854 | void | ||
| 855 | ) | ||
| 856 | { | ||
| 857 | ✗ | uint8_t mode; | |
| 858 | |||
| 859 | ✗ | LORA_STATUS mode_check = lora_read_register( LORA_REG_OPERATION_MODE, &mode ); | |
| 860 | ✗ | mode = mode & 0x07; | |
| 861 | |||
| 862 | ✗ | if( mode_check == LORA_OK && mode == LORA_RX_CONTINUOUS_MODE ) { | |
| 863 | ✗ | uint8_t irq_flag; | |
| 864 | |||
| 865 | ✗ | LORA_STATUS irq_check = lora_read_register(LORA_REG_IRQ_FLAGS, &irq_flag); | |
| 866 | |||
| 867 | ✗ | if( irq_check == LORA_OK ) { | |
| 868 | ✗ | lora_write_register( LORA_REG_IRQ_FLAGS, irq_flag ); | |
| 869 | ✗ | uint8_t rx_done = ( irq_flag & 0x40 ) == 0x40; | |
| 870 | |||
| 871 | ✗ | if( rx_done ) { | |
| 872 | ✗ | lora_rx_done = LORA_READY; | |
| 873 | ✗ | return LORA_READY; | |
| 874 | } else { | ||
| 875 | ✗ | lora_rx_done = LORA_WAITING; | |
| 876 | ✗ | return LORA_WAITING; | |
| 877 | } | ||
| 878 | } else { | ||
| 879 | return LORA_FAIL; | ||
| 880 | } | ||
| 881 | } else { | ||
| 882 | return LORA_FAIL; | ||
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | /******************************************************************************* | ||
| 887 | * * | ||
| 888 | * PROCEDURE: * | ||
| 889 | * lora_receive * | ||
| 890 | * * | ||
| 891 | * DESCRIPTION: * | ||
| 892 | * lora_receive: receive a buffer from lora fifo with continuous mode * | ||
| 893 | * * | ||
| 894 | *******************************************************************************/ | ||
| 895 | ✗ | LORA_STATUS lora_receive | |
| 896 | ( | ||
| 897 | uint8_t* buffer_ptr, | ||
| 898 | uint8_t buffer_len, | ||
| 899 | uint8_t* num_bytes_received | ||
| 900 | ) | ||
| 901 | { | ||
| 902 | ✗ | if ( lora_rx_done == LORA_READY ){ | |
| 903 | // Write IRQ flags | ||
| 904 | ✗ | uint8_t irq_flag; | |
| 905 | |||
| 906 | ✗ | LORA_STATUS irq_status2 = lora_read_register(LORA_REG_IRQ_FLAGS, &irq_flag); | |
| 907 | ✗ | if( irq_status2 != LORA_OK ) | |
| 908 | { | ||
| 909 | return LORA_FAIL; | ||
| 910 | } | ||
| 911 | ✗ | uint8_t crc_err = ( irq_flag & 0x20 ) == 0x20; | |
| 912 | |||
| 913 | ✗ | if (!crc_err){ // TODO make a fail happen for a CRC error | |
| 914 | // Read received number of bytes | ||
| 915 | ✗ | uint8_t num_bytes; | |
| 916 | ✗ | LORA_STATUS fifo2_status = lora_read_register(LORA_REG_FIFO_RX_NUM_BYTES, &num_bytes); | |
| 917 | |||
| 918 | // In case SPI operation fials | ||
| 919 | ✗ | if( fifo2_status != LORA_OK ) { | |
| 920 | return LORA_FAIL; | ||
| 921 | } | ||
| 922 | |||
| 923 | ✗ | if (num_bytes > buffer_len) | |
| 924 | { | ||
| 925 | return LORA_BUFFER_UNDERSIZED; | ||
| 926 | } | ||
| 927 | |||
| 928 | // Set lora fifo pointer to the RX base current address | ||
| 929 | ✗ | uint8_t fifo_ptr_addr; | |
| 930 | ✗ | LORA_STATUS base_adr_status = lora_read_register(LORA_REG_FIFO_RX_BASE_CUR_ADDR, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer | |
| 931 | ✗ | if (base_adr_status != LORA_OK){ | |
| 932 | // Error handler | ||
| 933 | return LORA_FAIL; | ||
| 934 | } | ||
| 935 | ✗ | LORA_STATUS ptr2_status = lora_write_register(LORA_REG_FIFO_SPI_POINTER, fifo_ptr_addr); // Set fifo data pointer to TX base address | |
| 936 | ✗ | if (ptr2_status != LORA_OK){ | |
| 937 | // Error handler | ||
| 938 | return LORA_FAIL; | ||
| 939 | } | ||
| 940 | // Begin extracting payload | ||
| 941 | ✗ | LORA_STATUS pld_xtr_status = LORA_OK; | |
| 942 | |||
| 943 | /* | ||
| 944 | // Old Rx buffer read code | ||
| 945 | // TODO don't remove until burst read is confirmed working | ||
| 946 | for (int i = 0; i < num_bytes; i++){ | ||
| 947 | uint8_t packet; | ||
| 948 | pld_xtr_status = lora_read_register(LORA_REG_FIFO_RW, &packet); // Access LoRA FIFO data buffer pointer | ||
| 949 | buffer_ptr[i] = packet; | ||
| 950 | } */ | ||
| 951 | |||
| 952 | ✗ | lora_read_register_buffer( LORA_REG_FIFO_RW, buffer_ptr, num_bytes); | |
| 953 | |||
| 954 | ✗ | *num_bytes_received = num_bytes; | |
| 955 | ✗ | if (pld_xtr_status == LORA_OK ) { | |
| 956 | ✗ | return LORA_OK; | |
| 957 | } else { | ||
| 958 | return LORA_FAIL; | ||
| 959 | } | ||
| 960 | } | ||
| 961 | return LORA_OK; | ||
| 962 | ✗ | } else if( lora_rx_done == LORA_WAITING ) { | |
| 963 | ✗ | return LORA_WAITING; | |
| 964 | } | ||
| 965 | return LORA_FAIL; | ||
| 966 | } | ||
| 967 | |||
| 968 | /*------------------------------------------------------------------------------ | ||
| 969 | Internal procedures | ||
| 970 | ------------------------------------------------------------------------------*/ | ||
| 971 |