Loading...
Searching...
No Matches
lora.c
1/***********************************************************************************
2 * @file lora.c *
3 * @author Matt Ricci *
4 * @addtogroup LoRa *
5 * @brief Brief description of the file's purpose. *
6 * *
7 * @todo Implement adjustable packet size *
8 * @{ *
9 ***********************************************************************************/
10
11#include "lora.h"
12
13/* SPI3 LORA
14 * ------------------------------------
15 * Flash Pin | MCU GPIO Pin | SIGNAL TYPE
16 * -----------|---------------|------------
17 * SDI | PC12 | DATA
18 * SDO | PC11 | DATA
19 * SCLK | PC10 | DATA
20 * RST | PD7 | CONTROL
21 * DI0 | PD1 | DATA
22 * CS | PD0 | CONTROL */
23
24/* =============================================================================== */
38 LoRa *lora,
39 char name[DEVICE_NAME_LENGTH],
40 GPIO_TypeDef *port,
41 unsigned long cs,
42 Bandwidth bw,
43 SpreadingFactor sf,
44 CodingRate cr
45) {
46 SPI_init(&lora->base, COMM_LORA, SPI3, MODE16, port, cs);
47 lora->transmit = LoRa_transmit;
48
49 _LoRa_setMode(lora, SLEEP); // Set mode to sleep
50
51 // Set interrupt pin
52 LoRa_writeRegister(lora, RegDioMapping1, 0x40);
53
54 /* clang-format off */
55 LoRa_writeRegister(lora, LORA_REG_OP_MODE,
56 0x01 << LORA_REG_OP_MODE_LONG_RANGE_Pos // Enable LoRa
57 );
58
59 LoRa_writeRegister(lora, LORA_REG_MODEM_CONFIG1,
60 bw << LORA_REG_MODEM_CONFIG1_BW_Pos // Set bandwidth
61 | cr << LORA_REG_MODEM_CONFIG1_CR_Pos // Set coding rate
62 | 0x00 << LORA_REG_MODEM_CONFIG1_CRC_Pos // Enable CRC
63 );
64 /* clang-format on */
65
67 LoRa_writeRegister(lora, LORA_REG_MODEM_CONFIG2, 0x94);
68
69 // Set payload length
70 LoRa_writeRegister(lora, LORA_REG_PAYLOAD_LENGTH, LORA_MSG_LENGTH);
71 LoRa_writeRegister(lora, LORA_REG_MAX_PAYLOAD_LENGTH, LORA_MSG_LENGTH);
72
73 _LoRa_setMode(lora, STDBY); // Set mode to standby
74
75 DeviceHandle_t handle;
76 strcpy(handle.name, name);
77 handle.device = lora;
78 return handle;
79}
80
81/********************************** PRIVATE METHODS ********************************/
82
83#ifndef DOXYGEN_PRIVATE
84
85/* =============================================================================== */
94void _LoRa_setMode(LoRa *lora, Mode mode) {
95 uint8_t regOpMode = LoRa_readRegister(lora, LORA_REG_OP_MODE);
96 regOpMode &= ~0x07; // Mask to mode bits
97 regOpMode |= mode; // Set mode
98 LoRa_writeRegister(lora, LORA_REG_OP_MODE, regOpMode);
99}
100
101#endif
102
103/********************************** STATIC METHODS *********************************/
104
105/* =============================================================================== */
123 uint8_t id,
124 uint8_t currentState,
125 uint8_t *lAccelData,
126 uint8_t *hAccelData,
127 uint8_t lenAccel,
128 uint8_t *gyroData,
129 uint8_t lenGyro,
130 float altitude,
131 float velocity
132) {
133 LoRa_Packet msg;
134
135 // Convert altitude float to byte array
136 union {
137 float f;
138 uint8_t b[4];
139 } a;
140 a.f = altitude;
141
142 // Convert velocity float to byte array
143 union {
144 float f;
145 uint8_t b[4];
146 } v;
147 v.f = velocity;
148
149 int idx = 0;
150 // Append to struct data array
151 msg.id = id;
152 msg.data[idx++] = currentState;
153 memcpy(&msg.data[idx], lAccelData, lenAccel);
154 memcpy(&msg.data[idx += lenAccel], hAccelData, lenAccel);
155 memcpy(&msg.data[idx += lenAccel], gyroData, lenGyro);
156 memcpy(&msg.data[idx += lenGyro], a.b, sizeof(float));
157 memcpy(&msg.data[idx += sizeof(float)], v.b, sizeof(float));
158
159 return msg;
160}
161
163 uint8_t id,
164 char *latitude,
165 char *longitude,
166 uint8_t flags
167) {
168 LoRa_Packet msg;
169
170 int idx = 0;
171 // Append to struct data array
172 msg.id = id;
173 memcpy(&msg.data[idx], latitude, 15);
174 memcpy(&msg.data[idx += 15], longitude, 15);
175 msg.data[idx += 15] = flags;
176
177 return msg;
178}
179
180LoRa_Packet LoRa_PayloadData(
181 uint8_t id,
182 uint8_t state,
183 uint8_t *accelData,
184 uint8_t lenAccelData
185) {
186 LoRa_Packet msg;
187
188 int idx = 0;
189 // Append to struct data array
190 msg.id = id;
191 msg.data[idx++] = state;
192 memcpy(&msg.data[idx+lenAccelData], accelData, lenAccelData);
193
194 return msg;
195}
196
197/********************************** DEVICE METHODS *********************************/
198
199/* =============================================================================== */
207void LoRa_transmit(LoRa *lora, uint8_t *pointerdata) {
208 LoRa_writeRegister(lora, LORA_REG_IRQ_FLAGS, 0x08); // clears the status flags
209 LoRa_writeRegister(lora, LORA_REG_FIFO_ADDR_PTR, 0x80); // set pointer adddress to TX
210
211 // Load data into transmit FIFO
212 for (int i = 0; i < 32; i++) {
213 LoRa_writeRegister(lora, LORA_REG_FIFO, pointerdata[i]);
214 }
215
216 // Set device to transmit
217 _LoRa_setMode(lora, TX);
218
219 // Clear the status flags
220 LoRa_writeRegister(lora, LORA_REG_IRQ_FLAGS, 0x08);
221}
222
223/******************************** INTERFACE METHODS ********************************/
224
225void LoRa_writeRegister(LoRa *lora, uint8_t address, uint8_t data) {
226 SPI spi = lora->base;
227
228 uint16_t payload = (address << 0x08) | (1 << 0x0F); // Load payload with address and write command
229 payload |= data; // Append data to payload
230 spi.port->ODR &= ~spi.cs; // Lower chip select
231 spi.transmit(&spi, payload); // Send payload over SPI
232 spi.port->ODR |= spi.cs; // Raise chip select
233}
234
235uint8_t LoRa_readRegister(LoRa *lora, uint8_t address) {
236 SPI spi = lora->base;
237 uint16_t response;
238
239 uint16_t payload = (address << 0x08); // Load payload with address and read command
240 spi.port->ODR &= ~spi.cs; // Lower chip select
241 response = spi.transmit(&spi, payload); // Receive payload over SPI
242 spi.port->ODR |= spi.cs; // Raise chip select
243 return (uint8_t)response;
244}
245
uint8_t id
Packet header ID.
Definition lora.h:90
uint8_t data[LORA_MSG_PAYLOAD_LENGTH]
Packet payload.
Definition lora.h:91
DeviceHandle_t LoRa_init(LoRa *lora, char name[DEVICE_NAME_LENGTH], GPIO_TypeDef *port, unsigned long cs, Bandwidth bw, SpreadingFactor sf, CodingRate cr)
Initializes the LoRa module with specified configuration parameters.
Definition lora.c:37
LoRa_Packet LoRa_GPSData(uint8_t id, char *latitude, char *longitude, uint8_t flags)
Definition lora.c:162
void _LoRa_setMode(LoRa *lora, Mode mode)
Sets the operational mode of the LoRa module.
Definition lora.c:94
LoRa_Packet LoRa_AVData(uint8_t id, uint8_t currentState, uint8_t *lAccelData, uint8_t *hAccelData, uint8_t lenAccel, uint8_t *gyroData, uint8_t lenGyro, float altitude, float velocity)
Constructs a LoRa packet with accelerometer and gyroscope data, altitude, and velocity for transmissi...
Definition lora.c:122
void LoRa_transmit(LoRa *, uint8_t *)
Transmits data using the LoRa module.
Definition lora.c:207
void SPI_init(SPI *, DeviceType, SPI_TypeDef *, DataFormat, GPIO_TypeDef *, unsigned long)
Initialiser for an SPI device interface.
Definition spi.c:32
@ COMM_LORA
LoRa module.
Definition spi.h:33
Definition lora.h:95
void(* transmit)(struct LoRa *, uint8_t *)
LoRa transmit method.
Definition lora.h:97
SPI base
Parent SPI interface.
Definition lora.h:96
Struct definition for SPI interface. Provides the interface for API consumers to interact with the SP...
Definition spi.h:49
uint16_t(* transmit)(struct SPI *, uint16_t)
SPI transmit method.
Definition spi.h:56
GPIO_TypeDef * port
Pointer to GPIO port struct.
Definition spi.h:52
unsigned long cs
Device chip select address.
Definition spi.h:53