Solaris Software
Loading...
Searching...
No Matches
sx1262.c
Go to the documentation of this file.
1/**
2 * @file sx1262.c
3 * @brief sx1262 module telemetry + SPP service implementation.
4 */
5
7
8#include <stdio.h>
9#include <string.h>
11#include "spp/core/packet.h"
12#include "spp/hal/spi.h"
13#include "spp/hal/gpio/gpio.h"
14#include "spp/hal/time/time.h"
15
16
17/* -----------------------------------------
18 VARIABLES
19--------------------------------------------*/
20static SPP_Packet_t mailboxData[K_SX1262_MAILBOX_SIZE] = {0};
21
25
27
29 .consumerID = K_SX1262_SERVICE_APID,
30 .priority = 1,
31 .p_nameConsumer = "sx1262",
32 .tiemoutMs = K_SX1262_TASK_TIMEOUT_MS,
34 .deliverToMailbox = SPP_SERVICES_SX1262_deliverToMailbox,
36};
37
38volatile spp_bool_t g_txDoneFlag = SPP_FALSE; // volatile para que no se optimice el bucle de espera
40
41
42/* -----------------------------------------
43 STATIC FUNCTIONS DECLARATIONS
44--------------------------------------------*/
49
50static void SPP_SERVICES_SX1262_bmpPacket_to_text(SPP_Packet_t *p_pkt, char *dataStr);
51static void SPP_SERVICES_SX1262_icmPacket_to_text(SPP_Packet_t *p_pkt, char *dataStr);
52
53
54/* -----------------------------------------
55 STATIC FUNCTIONS IMPLEMENTATION
56--------------------------------------------*/
60
61 return ret;
62}
63
65
66 if (mailboxCount < K_SX1262_MAILBOX_SIZE){
67 mailboxData[mailboxTail] = *p_pqt;
68 mailboxTail = (spp_uint8_t)((mailboxTail + 1U) % K_SX1262_MAILBOX_SIZE); // suma circular
69 mailboxCount++; // usaremos mailboxCount para saber cuantos paquetes tendremos que enviar luego
70 return K_SPP_OK;
71 }
72 else{
73 return K_SPP_ERROR;
74 }
75}
76
77// HAY QUE CAMBIAR ESTO
79 char sensorsStr[256];
80 char strBMP390[64];
81 char strICM20948[128];
82
83 while (mailboxCount > 0) {
85
86 sprintf(strBMP390, "BMP390:-");
87 sprintf(strICM20948, "ICM20948:-");
88
89 spp_uint8_t packetAPID = packet.primaryHeader.apid;
90 if (packetAPID == K_BMP390_SERVICE_APID){
91 SPP_SERVICES_SX1262_bmpPacket_to_text(&packet, strBMP390);
92 }
93 else if(packetAPID == K_ICM20948_SERVICE_APID){
94 SPP_SERVICES_SX1262_icmPacket_to_text(&packet, strICM20948);
95 }
96
97 sprintf(sensorsStr, "%s,%s,", strBMP390, strICM20948);
98
99 SPP_SERVICES_SX1262_send_frame(s_frame_number, sensorsStr);
101
102 mailboxHead = (mailboxHead + 1U) % K_SX1262_MAILBOX_SIZE;
103 mailboxCount--;
104 }
105
106 return K_SPP_OK;
107}
108
112
113SPP_RetVal_t SX1262_Transmit(void *p_handle, spp_uint8_t *p_data, spp_uint8_t length)
114{
115 SPP_RetVal_t ret;
116
117 // Secuencia de configuración base y radio
118 ret = SX1262_SetStandby(p_handle);
119 if (ret != K_SPP_OK) return ret;
120
121 ret = SX1262_SetPacketType(p_handle);
122 if (ret != K_SPP_OK) return ret;
123
124 ret = SX1262_SetRfFrequency(p_handle);
125 if (ret != K_SPP_OK) return ret;
126
127 ret = SX1262_SetPaConfig(p_handle);
128 if (ret != K_SPP_OK) return ret;
129
130 ret = SX1262_CalibrateImage(p_handle);
131 if (ret != K_SPP_OK) return ret;
132
133 ret = SX1262_SetTxParams(p_handle);
134 if (ret != K_SPP_OK) return ret;
135
136 // Gestión de memoria
137 ret = SX1262_SetBufferBaseAddress(p_handle);
138 if (ret != K_SPP_OK) return ret;
139
140 ret = SX1262_WriteBuffer(p_handle, p_data, length);
141 if (ret != K_SPP_OK) return ret;
142
143 // Parámetros de modulación y paquete LoRa
144 // SF7, BW 125kHz, CR 4/5, LDRO OFF
145 ret = SX1262_SetModulationParams(p_handle, 0x07, 0x04, 0x01, 0x00);
146 if (ret != K_SPP_OK) return ret;
147
148 // Preambulo = 8 simbolos, Paquete variable, Longitud del String, CRC ON
149 ret = SX1262_SetPacketParams(p_handle, 0x0008, length);
150 if (ret != K_SPP_OK) return ret;
151
152 // Configuración de Interrupciones en DIO1 (TxDone + Timeout)
153 ret = SX1262_SetDioIrqParams(p_handle, 0x0201, 0x0201, 0x0000, 0x0000);
154 if (ret != K_SPP_OK) return ret;
155
156 // Limpiar bandera
157 g_txDoneFlag = SPP_FALSE;
158
159 // Ejecutar transmision (SetTx con 1 seg timeout: 0x00FA00)
160 ret = SX1262_SetTx(p_handle, 0x00FA00);
161 if (ret != K_SPP_OK) return ret;
162
163 // Esperar a que la ISR active la bandera de finalización
164 ret = SX1262_WaitForTxDone(p_handle);
165
166 return ret;
167}
168
169// ESTA FUNCION NO SE USARA
170static void SPP_SERVICES_SX1262_bmpPacket_to_text(SPP_Packet_t *p_pkt, char *dataStr){
171 float *payload = (float *)p_pkt->payload;
172
173 float altitude = payload[0];
174 float pressure = payload[1];
175 float temperature = payload[2];
176
177 sprintf(dataStr, "BMP390:alt=%.1f|P=%.1f|T=%.2f", altitude, pressure, temperature);
178
179 return;
180}
181
182// ESTA FUNCION NO SE USARA
183static void SPP_SERVICES_SX1262_icmPacket_to_text(SPP_Packet_t *p_pkt, char *dataStr){
184 float *payload = (float *)p_pkt->payload;
185
186 float ax = payload[0];
187 float ay = payload[1];
188 float az = payload[2];
189 float gx = payload[3];
190 float gy = payload[4];
191 float gz = payload[5];
192 float mx = payload[6];
193 float my = payload[7];
194 float mz = payload[8];
195
196 sprintf(dataStr, "ICM20948:ax=%.2f|ay=%.2f|az=%.2f|gx=%.2f|gy=%.2f|gz=%.2f|mx=%.2f|my=%.2f|mz=%.2f", ax, ay, az, gx, gy, gz, mx, my, mz);
197
198 return;
199}
200
201/* -----------------------------------------
202 STATE CHANGES
203--------------------------------------------*/
205{
206 spp_uint8_t buffer[2];
207 buffer[0] = SX1262_OPCODE_SET_STANDBY; // Opcode SetStandby
208 buffer[1] = 0x00; // STDBY_RC (sin TXCO)
209
211 if (ret != K_SPP_OK)
212 return ret;
213 return SPP_HAL_SPI_transmit(p_handle, buffer, 2);
214}
215
216SPP_RetVal_t SX1262_SetTx(void *p_handle, spp_uint32_t timeout)
217{
218 // SetTx requiere 1 byte de Opcode y 3 bytes de parámetros
219 spp_uint8_t buffer[4];
220
221 buffer[0] = SX1262_OPCODE_SET_TX;
222 buffer[1] = (spp_uint8_t)((timeout >> 16) & 0xFF);
223 buffer[2] = (spp_uint8_t)((timeout >> 8) & 0xFF);
224 buffer[3] = (spp_uint8_t)(timeout & 0xFF);
225
227 if (ret != K_SPP_OK)
228 return ret;
229
230 ret = SPP_HAL_SPI_transmit(p_handle, buffer, 4);
231
232 return ret;
233}
234
235
236/* -----------------------------------------
237 BASIC PARAMETERS
238--------------------------------------------*/
240{
241 // LoRa
242 spp_uint8_t buffer[2];
244 buffer[1] = 0x01; // Protocolo LoRa
245
247 if (ret != K_SPP_OK)
248 return ret;
249 return SPP_HAL_SPI_transmit(p_handle, buffer, 2);
250}
251
253{
254 spp_uint8_t buffer[5];
256 buffer[1] = 0x36; // 868 MHz
257 buffer[2] = 0x40;
258 buffer[3] = 0x00;
259 buffer[4] = 0x00;
260
262 if (ret != K_SPP_OK)
263 return ret;
264 return SPP_HAL_SPI_transmit(p_handle, buffer, 5);
265}
266
268{
269 spp_uint8_t buffer[5];
270 buffer[0] = SX1262_OPCODE_SET_PA_CONFIG;
271 buffer[1] = 0x02; // paDutyCycle para +14 dBm en SX1262
272 buffer[2] = 0x02; // hpMax para +14 dBm en SX1262
273 buffer[3] = 0x00; // deviceSel --> SX1262
274 buffer[4] = 0x01; // paLut
275
277 if (ret != K_SPP_OK)
278 return ret;
279 return SPP_HAL_SPI_transmit(p_handle, buffer, 5);
280}
281
283{
284 spp_uint8_t buffer[3];
286 buffer[1] = 0xD7; // Calibracion para 868 MHz
287 buffer[2] = 0xDB;
288
290 if (ret != K_SPP_OK)
291 return ret;
292
293 return SPP_HAL_SPI_transmit(p_handle, buffer, 3);
294}
295
297{
298 spp_uint8_t buffer[3];
299 buffer[0] = SX1262_OPCODE_SET_TX_PARAMS;
300 buffer[1] = 0x16; // power: +22 dBm (por las restricciones puestas en SetPaConfig --> bajara a +14 dBm)
301 buffer[2] = 0x04; // RampTime: 200 us (valor intermedio)
302
304 if (ret != K_SPP_OK)
305 return ret;
306 return SPP_HAL_SPI_transmit(p_handle, buffer, 3);
307}
308
309/* -----------------------------------------
310 MEMORY MANAGEMENT
311--------------------------------------------*/
313{
314 spp_uint8_t buffer[3];
316 buffer[1] = 0x00; // txBaseAddress
317 buffer[2] = 0x00; // rxBaseAddress
318
320 if (ret != K_SPP_OK)
321 return ret;
322 return SPP_HAL_SPI_transmit(p_handle, buffer, 3);
323}
324
326{
327 /* La longitud maxima del buffer es 255 bytes
328 Sumando 1 byte de Opcode y 1 byte de Offset, el array máximo es de 257 bytes */
329 spp_uint8_t buffer[257];
330
331 buffer[0] = SX1262_OPCODE_WRITE_BUFFER;
332 buffer[1] = 0x00; // donde se empezará a escribir
333
334 for (spp_uint8_t i = 0; i < length; i++)
335 {
336 buffer[2 + i] = p_data[i];
337 }
338
340 if (ret != K_SPP_OK)
341 return ret;
342
343 // La longitud total de la transacción SPI es la longitud + 2 bytes de cabecera
344 return SPP_HAL_SPI_transmit(p_handle, buffer, length + 2);
345}
346
347/* -----------------------------------------
348 LoRa Parameters
349--------------------------------------------*/
351{
352 spp_uint8_t buffer[5];
354 buffer[1] = sf;
355 buffer[2] = bw;
356 buffer[3] = cr;
357 buffer[4] = ldro;
358
360 if (ret != K_SPP_OK)
361 return ret;
362 return SPP_HAL_SPI_transmit(p_handle, buffer, 5);
363}
364
365SPP_RetVal_t SX1262_SetPacketParams(void *p_handle, spp_uint16_t preambleLength, spp_uint8_t payloadLength)
366{
367 // El comando requiere 9 bytes de parámetros según la estructura genérica (10 bytes total) (para LoRa solo los 6 primeros)
368 spp_uint8_t buffer[10] = {0}; // Inicializa todo a 0
369
371 buffer[1] = (spp_uint8_t)(preambleLength >> 8); // MSB
372 buffer[2] = (spp_uint8_t)(preambleLength & 0xFF); // LSB
373 buffer[3] = 0x00; // Longitud de paquete variable (explicit header)
374 buffer[4] = payloadLength; // Longitud exacta de tu String en bytes
375 buffer[5] = 0x01; // CRC ON
376 buffer[6] = 0x00; // Standard IQ
377
379 if (ret != K_SPP_OK)
380 return ret;
381 return SPP_HAL_SPI_transmit(p_handle, buffer, 10);
382}
383
384/* -----------------------------------------
385 Interruption Management
386--------------------------------------------*/
387SPP_RetVal_t SX1262_SetDioIrqParams(void *p_handle, spp_uint16_t irqMask, spp_uint16_t dio1Mask, spp_uint16_t dio2Mask, spp_uint16_t dio3Mask)
388{
389 spp_uint8_t buffer[9];
391 buffer[1] = (spp_uint8_t)(irqMask >> 8);
392 buffer[2] = (spp_uint8_t)(irqMask & 0xFF);
393 buffer[3] = (spp_uint8_t)(dio1Mask >> 8);
394 buffer[4] = (spp_uint8_t)(dio1Mask & 0xFF);
395 buffer[5] = (spp_uint8_t)(dio2Mask >> 8);
396 buffer[6] = (spp_uint8_t)(dio2Mask & 0xFF);
397 buffer[7] = (spp_uint8_t)(dio3Mask >> 8);
398 buffer[8] = (spp_uint8_t)(dio3Mask & 0xFF);
399
401 return SPP_HAL_SPI_transmit(p_handle, buffer, 9);
402}
403
405{
406 spp_uint8_t buffer[3];
408 buffer[1] = (spp_uint8_t)(clearMask >> 8);
409 buffer[2] = (spp_uint8_t)(clearMask & 0xFF);
410
412 if (ret != K_SPP_OK)
413 return ret;
414
415 return SPP_HAL_SPI_transmit(p_handle, buffer, 3);
416}
417
419{
420 // Configura el pin como entrada con interrupción por flanco de subida
422
423 // Registra el contexto para que la ISR modifique g_txDoneFlag
425}
426
428{
429 const spp_uint32_t TIMEOUT_MAX_MS = 2000; // ms
430 spp_uint32_t startTime = SPP_HAL_TIME_getMs();
431
432 // Bucle de espera consultando la bandera modificada por la ISR
433 while (g_txDoneFlag == SPP_FALSE)
434 {
435 if ((SPP_HAL_TIME_getMs() - startTime) >= TIMEOUT_MAX_MS)
436 {
437 return K_ERROR;
438 }
439 }
440
441 // Restablece la bandera lógica para la próxima transmisión
442 g_txDoneFlag = SPP_FALSE;
443
444 // Limpia la bandera física en el registro interno del SX1262 enviando 0x0201
445 return SX1262_ClearIrqStatus(p_handle, 0x0201);
446}
447
448/* -----------------------------------------
449 AUXILIAR FUNCTION (Espera a que el chip acabe cualquier operacion que esté haciendo)
450--------------------------------------------*/
452{
453 const spp_uint32_t TIMEOUT_MAX_MS = 1000; // en milisegundos
454
455 spp_uint32_t startTime = SPP_HAL_TIME_getMs();
456
457 while (SPP_HAL_GPIO_read(SX1262_BUSY_PIN) == 1) // esta funcion en el HAL no existe, hay que crearla
458 {
459 // Verifica si se ha superado el tiempo máximo de espera
460 if ((SPP_HAL_TIME_getMs() - startTime) >= TIMEOUT_MAX_MS)
461 {
462 return K_ERROR;
463 }
464 }
465
466 return K_SPP_OK;
467}
SPP_RetVal_t SPP_HAL_GPIO_registerIsr(spp_uint32_t pin, void *p_isrCtx)
Register an ISR handler for a GPIO pin.
Definition gpio.c:39
SPP_RetVal_t SPP_HAL_GPIO_configInterrupt(spp_uint32_t pin, spp_uint32_t intrType, spp_uint32_t pull)
Configure a GPIO pin as an interrupt input.
Definition gpio.c:19
SPP GPIO HAL API — dispatches through the registered HAL port.
#define K_ICM20948_SERVICE_APID
Definition icm20948.h:42
Solaris Packet Protocol (SPP) packet structure definitions.
SPP_Packet_t
Definition packet.h:79
SPP_RetVal_t
Unified return type for all SPP API functions.
Definition returnTypes.h:24
@ K_SPP_OK
Definition returnTypes.h:25
@ K_SPP_ERROR
Definition returnTypes.h:26
SPP_RetVal_t SPP_HAL_SPI_transmit(void *p_handle, spp_uint8_t *p_data, spp_uint8_t length)
Perform a full-duplex SPI transaction.
Definition spi.c:79
Context passed to the GPIO ISR handler.
Definition gpio.h:27
Describes the contract of a consumer module. This module needs to have:
Definition service.h:43
SPP_RetVal_t SX1262_SetTxParams(void *p_handle)
Definition sx1262.c:296
static SPP_Packet_t mailboxData[K_SX1262_MAILBOX_SIZE]
Definition sx1262.c:20
SPP_RetVal_t SX1262_SetDioIrqParams(void *p_handle, spp_uint16_t irqMask, spp_uint16_t dio1Mask, spp_uint16_t dio2Mask, spp_uint16_t dio3Mask)
Definition sx1262.c:387
static spp_uint32_t s_frame_number
Definition sx1262.c:26
static SPP_SERVICE_ConsumerContract_t SPP_SERVICES_SX1262_getConsumerContract()
Definition sx1262.c:109
void SX1262_InitInterrupts(void)
Definition sx1262.c:418
SPP_RetVal_t SX1262_SetPacketType(void *p_handle)
Definition sx1262.c:239
SPP_RetVal_t SX1262_SetModulationParams(void *p_handle, spp_uint8_t sf, spp_uint8_t bw, spp_uint8_t cr, spp_uint8_t ldro)
Definition sx1262.c:350
SPP_RetVal_t SX1262_ClearIrqStatus(void *p_handle, spp_uint16_t clearMask)
Definition sx1262.c:404
static spp_uint8_t mailboxTail
Definition sx1262.c:23
SPP_GpioIsrCtx_t g_dio1Ctx
Definition sx1262.c:39
SPP_RetVal_t SX1262_WriteBuffer(void *p_handle, spp_uint8_t *p_data, spp_uint8_t length)
Definition sx1262.c:325
SPP_RetVal_t SX1262_WaitForTxDone(void *p_handle)
Definition sx1262.c:427
SPP_RetVal_t SX1262_WaitBusy(void)
Definition sx1262.c:451
SPP_RetVal_t SX1262_SetRfFrequency(void *p_handle)
Definition sx1262.c:252
static void SPP_SERVICES_SX1262_icmPacket_to_text(SPP_Packet_t *p_pkt, char *dataStr)
Definition sx1262.c:183
static SPP_RetVal_t SPP_SERVICES_SX1262_consumeData(void *p_data)
Definition sx1262.c:78
static SPP_RetVal_t SPP_SERVICES_SX1262_deliverToMailbox(const SPP_Packet_t p_pkt)
Definition sx1262.c:64
static void SPP_SERVICES_SX1262_bmpPacket_to_text(SPP_Packet_t *p_pkt, char *dataStr)
Definition sx1262.c:170
SPP_RetVal_t SX1262_SetPaConfig(void *p_handle)
Definition sx1262.c:267
volatile spp_bool_t g_txDoneFlag
Definition sx1262.c:38
static SPP_SERVICE_ConsumerContract_t sx1262Contract
Definition sx1262.c:28
SPP_RetVal_t SX1262_SetTx(void *p_handle, spp_uint32_t timeout)
Definition sx1262.c:216
static spp_uint8_t mailboxHead
Definition sx1262.c:22
static SPP_RetVal_t SPP_SERVICES_SX1262_init(void)
Definition sx1262.c:57
SPP_RetVal_t SX1262_SetPacketParams(void *p_handle, spp_uint16_t preambleLength, spp_uint8_t payloadLength)
Definition sx1262.c:365
SPP_RetVal_t SX1262_SetStandby(void *p_handle)
Definition sx1262.c:204
SPP_RetVal_t SX1262_SetBufferBaseAddress(void *p_handle)
Definition sx1262.c:312
static spp_uint8_t mailboxCount
Definition sx1262.c:24
SPP_RetVal_t SX1262_Transmit(void *p_handle, spp_uint8_t *p_data, spp_uint8_t length)
Definition sx1262.c:113
SPP_RetVal_t SX1262_CalibrateImage(void *p_handle)
Definition sx1262.c:282
#define SX1262_OPCODE_SET_BUFFER_BASE_ADDRESS
Definition sx1262.h:18
#define SX126X_DIO1_PIN
Definition sx1262.h:27
#define SX1262_OPCODE_SET_PA_CONFIG
Definition sx1262.h:16
#define SX1262_OPCODE_SET_RF_FRECUENCY
Definition sx1262.h:15
#define SX1262_OPCODE_SET_STANDBY
Definition sx1262.h:12
#define SX1262_BUSY_PIN
Definition sx1262.h:26
#define SX1262_OPCODE_CALIBRATE_IMAGE
Definition sx1262.h:24
#define SX1262_OPCODE_WRITE_BUFFER
Definition sx1262.h:19
#define SX1262_OPCODE_SET_TX_PARAMS
Definition sx1262.h:17
#define SX1262_OPCODE_SET_MODULATION_PARAMS
Definition sx1262.h:20
#define SX1262_OPCODE_CLEAR_IRQ_STATUS
Definition sx1262.h:23
#define SX1262_OPCODE_SET_TX
Definition sx1262.h:13
#define SX1262_OPCODE_SET_PACKET_TYPE
Definition sx1262.h:14
#define SX1262_OPCODE_SET_PACKET_PARAMS
Definition sx1262.h:21
#define SX1262_OPCODE_SET_DIO_IRQ_PARAMS
Definition sx1262.h:22
SPP HAL time API — dispatches through the registered HAL port.
uint16_t spp_uint16_t
Definition types.h:29
uint32_t spp_uint32_t
Definition types.h:31
uint8_t spp_uint8_t
Definition types.h:27
bool spp_bool_t
Definition types.h:36