Loading...
Searching...
No Matches
sx1272.c
1/**************************************************************************************************
2 * @file sx1272.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 "sx1272.h"
12
13/* ============================================================================================== */
28 SX1272_t *lora,
29 SPI_t *spi,
30 GPIOpin_t cs,
34) {
35 lora->base = spi;
36 lora->cs = cs;
37 lora->standby = SX1272_standby;
43
44 // Set mode to sleep
45 _SX1272_setMode(lora, SX1272_MODE_SLEEP);
46
47 /* clang-format off */
48 SX1272_writeRegister(lora, SX1272_REG_OP_MODE,
49 0x01 << SX1272_OP_MODE_LONG_RANGE_Pos // Enable LoRa
50 );
51
52 SX1272_writeRegister(lora, SX1272_REG_MODEM_CONFIG1,
53 bw << SX1272_REG_MODEM_CONFIG1_BW_Pos // Set bandwidth
54 | cr << SX1272_REG_MODEM_CONFIG1_CR_Pos // Set coding rate
55 | 0x00 << SX1272_REG_MODEM_CONFIG1_CRC_Pos // Enable CRC
56 );
57 /* clang-format on */
58
59 // TODO: make this configurable in driver
60 //
61 // Set spreading factor
62 SX1272_writeRegister(lora, SX1272_REG_MODEM_CONFIG2, 0x94);
63
64 // Set payload length
65 SX1272_writeRegister(lora, SX1272_REG_PAYLOAD_LENGTH, LORA_MSG_LENGTH);
66 SX1272_writeRegister(lora, SX1272_REG_MAX_PAYLOAD_LENGTH, LORA_MSG_LENGTH);
67
68 // TODO: make this configurable in driver
69 //
70 // Set FIFO base addresses
71 SX1272_writeRegister(lora, SX1272_REG_FIFO_TX_BASE_ADDR, 0x00); // Tx starts at 0x00
72 SX1272_writeRegister(lora, SX1272_REG_FIFO_RX_BASE_ADDR, 0x00); // Rx starts at 0x00
73
74 // Set mode to standby
75 _SX1272_setMode(lora, SX1272_MODE_STDBY);
76
77 return *lora;
78}
79
80#ifndef DOXYGEN_PRIVATE
81
82/**************************************** PRIVATE METHODS *****************************************/
83
84/* ============================================================================================== */
94 uint8_t regOpMode = SX1272_readRegister(lora, SX1272_REG_OP_MODE);
95 regOpMode &= ~0x07; // Mask to mode bits
96 regOpMode |= mode; // Set mode
97 SX1272_writeRegister(lora, SX1272_REG_OP_MODE, regOpMode);
98}
99
100#endif
101
102/***************************************** PUBLIC METHODS *****************************************/
103
104/* ============================================================================================== */
114void SX1272_enableBoost(SX1272_t *lora, bool enable) {
115 uint8_t regPaConfig = SX1272_readRegister(lora, SX1272_REG_PA_CONFIG); // Read current config
116 regPaConfig &= ~SX1272_PA_SELECT; // Mask out PA select bit
117 SX1272_writeRegister(lora, SX1272_REG_PA_CONFIG, regPaConfig | SX1272_PA_SELECT);
118}
119
120/* ============================================================================================== */
130 _SX1272_setMode(lora, SX1272_MODE_STDBY);
131}
132
133/* ============================================================================================== */
141void SX1272_transmit(SX1272_t *lora, uint8_t *pointerdata) {
142 // Set device to standby
143 _SX1272_setMode(lora, SX1272_MODE_STDBY);
144
145 // TODO: add in proper read-mask-write operation for setting DIO mapping
146 //
147 // Set DIO interrupt pin to TxDone
148 SX1272_writeRegister(lora, SX1272_REG_DIO_MAPPING1, SX1272_LORA_DIO_TXDONE);
149
150 // Since the device will only ever be transmitting or receiving at any given time
151 // and each packet should be handled immediately by the implementation (no waiting
152 // on buffering), we don't need to be concerned about the buffer being overwritten.
153 //
154 // ...for now.
155
156 // TODO:
157 // Think of a more elegant solution for applications that might use this
158 // driver that want buffered data
159 //
160 // Clear IRQ flags and set FIFO address pointer.
161 SX1272_writeRegister(lora, SX1272_REG_IRQ_FLAGS, SX1272_LORA_IRQ_TXDONE); // clears the IRQ flag
162 SX1272_writeRegister(lora, SX1272_REG_FIFO_ADDR_PTR, 0x00); // set pointer adddress to start
163
164 // Load data into transmit FIFO
165 for (int i = 0; i < 32; i++) {
166 SX1272_writeRegister(lora, SX1272_REG_FIFO, pointerdata[i]);
167 }
168
169 // Update the current operating mode
170 lora->currentMode = SX1272_MODE_TX; // Set local mode setting
171 _SX1272_setMode(lora, lora->currentMode); // Start transmitting
172}
173
174/* ============================================================================================== */
182 // Set device to standby
183 _SX1272_setMode(lora, SX1272_MODE_STDBY);
184
185 // TODO: add in proper read-mask-write operation for setting DIO mapping
186 //
187 // Set DIO interrupt pin to RxDone
188 SX1272_writeRegister(lora, SX1272_REG_DIO_MAPPING1, SX1272_LORA_DIO_RXDONE);
189
190 // Since the device will only ever be transmitting or receiving at any given time
191 // and each packet should be handled immediately by the implementation (no waiting
192 // on buffering), we don't need to be concerned about the buffer being overwritten.
193 //
194 // ...for now.
195
196 // TODO:
197 // Think of a more elegant solution for applications that might use this
198 // driver that want buffered data
199 //
200 // Clear IRQ flags and set FIFO address pointer.
201 SX1272_writeRegister(lora, SX1272_REG_IRQ_FLAGS, SX1272_LORA_IRQ_RXDONE); // Clear the IRQ flag
202 SX1272_writeRegister(lora, SX1272_REG_FIFO_ADDR_PTR, 0x00); // Set pointer adddress to start
203
204 // Update the current operating mode
205 lora->currentMode = SX1272_MODE_RXCONTINUOUS; // Set local mode setting
206 _SX1272_setMode(lora, lora->currentMode); // Start receiving
207}
208
209/* ============================================================================================== */
221bool SX1272_readReceive(SX1272_t *lora, uint8_t *buffer, uint8_t buffSize) {
222
223 // TODO: Error handling for IRQ flags
224 //
225 // Currently the readReceive() method clears the SX1272 RxDone IRQ flag before
226 // starting the read. This is fine for cases where the user code carefully
227 // manages the DIO interrupts, however ideally the method should check for
228 // errors in the IRQ register and appropriately discard received packets.
229
230 // Clear the IRQ flag
231 SX1272_writeRegister(lora, SX1272_REG_IRQ_FLAGS, SX1272_LORA_IRQ_RXDONE);
232
233 // Read address and packet width information of received data
234 uint8_t bytesReceived = SX1272_readRegister(lora, SX1272_REG_RX_BYTES); // Number of bytes received
235 uint8_t rxCurrentAddr = SX1272_readRegister(lora, SX1272_REG_FIFO_RX_CURR_ADDR); // Address of last packet
236
237 // Return error if buffer is smaller than the received data
238 if (bytesReceived > buffSize)
239 return false;
240
241 // Otherwise, set the address pointer and read each byte into buffer
242 SX1272_writeRegister(lora, SX1272_REG_FIFO_ADDR_PTR, rxCurrentAddr);
243 for (int i = 0; i < bytesReceived; i++) {
244 buffer[i] = SX1272_readRegister(lora, SX1272_REG_FIFO);
245 }
246
247 return true;
248}
249
250/* ============================================================================================== */
261void SX1272_clearIRQ(SX1272_t *lora, uint8_t flags) {
262 SX1272_writeRegister(lora, SX1272_REG_IRQ_FLAGS, flags);
263}
264
265/*************************************** INTERFACE METHODS ****************************************/
266
267void SX1272_writeRegister(SX1272_t *lora, uint8_t address, uint8_t data) {
268 SPI_t *spi = lora->base;
269 GPIOpin_t cs = lora->cs;
270
271 // Pull CS low
272 cs.reset(&cs);
273
274 // Send write data and address
275 uint8_t payload = address | 0x80; // Load payload with address and write command
276 spi->transmit(spi, payload); // Transmit payload
277 spi->transmit(spi, data); // Transmit write data
278
279 // Set CS high
280 cs.set(&cs);
281}
282
283uint8_t SX1272_readRegister(SX1272_t *lora, uint8_t address) {
284 uint8_t response = 0;
285 SPI_t *spi = lora->base;
286 GPIOpin_t cs = lora->cs;
287
288 // Pull CS low
289 cs.reset(&cs);
290
291 // Send write data and address
292 uint8_t payload = address & 0x7F; // Load payload with address and read command
293 response = spi->transmit(spi, payload); // Transmit payload
294 response = spi->transmit(spi, 0xFF); // Transmit dummy data and reasd response
295
296 // Set CS high
297 cs.set(&cs);
298
299 return response;
300}
301
void(* set)(struct GPIOpin *)
Definition gpiopin.h:155
void(* reset)(struct GPIOpin *)
Definition gpiopin.h:156
Struct definition for a GPIO pin.
Definition gpiopin.h:151
uint16_t(* transmit)(struct SPI *, uint16_t)
SPI transmit method.
Definition spi.h:139
Struct definition for SPI interface. Provides the interface for API consumers to interact with the SP...
Definition spi.h:134
void(* enableBoost)(struct SX1272 *, bool)
Power amp boost toggle method.
Definition sx1272.h:137
void(* standby)(struct SX1272 *)
SX1272 standby method.
Definition sx1272.h:138
void(* startReceive)(struct SX1272 *)
SX1272 LoRa continuous receive method.
Definition sx1272.h:140
bool(* readReceive)(struct SX1272 *, uint8_t *, uint8_t)
SX1272 LoRa receive buffer read method.
Definition sx1272.h:141
GPIOpin_t cs
Chip select GPIO.
Definition sx1272.h:135
void(* transmit)(struct SX1272 *, uint8_t *)
SX1272 LoRa transmit method.
Definition sx1272.h:139
SPI_t * base
Parent SPI interface.
Definition sx1272.h:134
void(* clearIRQ)(struct SX1272 *, uint8_t)
SX1272 LoRa IRQ flag clear method.
Definition sx1272.h:142
SX1272_Mode currentMode
Current operating mode.
Definition sx1272.h:136
void SX1272_transmit(SX1272_t *, uint8_t *)
Transmits data using the SX1272.
Definition sx1272.c:141
SX1272_Bandwidth
SX1272 bandwidth enum.
Definition sx1272.h:76
void _SX1272_setMode(SX1272_t *lora, SX1272_Mode mode)
Sets the operational mode of the LoRa module.
Definition sx1272.c:93
bool SX1272_readReceive(SX1272_t *, uint8_t *, uint8_t)
Reads contents of received packet to local buffer from the SX1272.
Definition sx1272.c:221
SX1272_SpreadingFactor
SX1272 spreading factor enum.
Definition sx1272.h:99
SX1272_Mode
SX1272 operating mode enum.
Definition sx1272.h:113
void SX1272_standby(SX1272_t *)
Sets the operational mode of the LoRa module to standby.
Definition sx1272.c:129
SX1272_t SX1272_init(SX1272_t *lora, SPI_t *spi, GPIOpin_t cs, SX1272_Bandwidth bw, SX1272_SpreadingFactor sf, SX1272_CodingRate cr)
Initializes the LoRa module with specified configuration parameters.
Definition sx1272.c:27
SX1272_CodingRate
SX1272 coding rate enum.
Definition sx1272.h:87
void SX1272_startReceive(SX1272_t *)
Begins continuous receive on the SX1272.
Definition sx1272.c:181
void SX1272_enableBoost(SX1272_t *, bool)
Enables/disables power amplifier boost.
Definition sx1272.c:114
void SX1272_clearIRQ(SX1272_t *, uint8_t)
Sets the value of RegIrqFlags in the SX1272 to the provided argument value. Writing a 1 to a bit in t...
Definition sx1272.c:261
Struct definition for SX1272. Provides the interface for API consumers to interact with the SX1272 Lo...
Definition sx1272.h:133