From f8c5915356d135f78b88949677ec45ffe2a335aa Mon Sep 17 00:00:00 2001 From: niekky Date: Fri, 10 Nov 2023 22:14:27 -0700 Subject: [PATCH 01/60] Added SMotlaq LoRa Lib Code --- LoRa/LoRa.c | 534 ++++++++++++++++++++++++++++++++++++++++++++++++++++ LoRa/LoRa.h | 129 +++++++++++++ 2 files changed, 663 insertions(+) create mode 100644 LoRa/LoRa.c create mode 100644 LoRa/LoRa.h diff --git a/LoRa/LoRa.c b/LoRa/LoRa.c new file mode 100644 index 0000000..3d1f2bb --- /dev/null +++ b/LoRa/LoRa.c @@ -0,0 +1,534 @@ +#include "LoRa.h" + +/* ----------------------------------------------------------------------------- *\ + name : newLoRa + + description : it's a constructor for LoRa structure that assign default values + and pass created object (LoRa struct instanse) + + arguments : Nothing + + returns : A LoRa object whith these default values: + ---------------------------------------- + | carrier frequency = 433 MHz | + | spreading factor = 7 | + | bandwidth = 125 KHz | + | coding rate = 4/5 | + ---------------------------------------- +\* ----------------------------------------------------------------------------- */ +LoRa newLoRa(){ + LoRa new_LoRa; + + new_LoRa.frequency = 433 ; + new_LoRa.spredingFactor = SF_7 ; + new_LoRa.bandWidth = BW_125KHz ; + new_LoRa.crcRate = CR_4_5 ; + new_LoRa.power = POWER_20db; + new_LoRa.overCurrentProtection = 100 ; + new_LoRa.preamble = 8 ; + + return new_LoRa; +} +/* ----------------------------------------------------------------------------- *\ + name : LoRa_reset + + description : reset module + + arguments : + LoRa* LoRa --> LoRa object handler + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_reset(LoRa* _LoRa){ + HAL_GPIO_WritePin(_LoRa->reset_port, _LoRa->reset_pin, GPIO_PIN_RESET); + HAL_Delay(1); + HAL_GPIO_WritePin(_LoRa->reset_port, _LoRa->reset_pin, GPIO_PIN_SET); + HAL_Delay(100); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_gotoMode + + description : set LoRa Op mode + + arguments : + LoRa* LoRa --> LoRa object handler + mode --> select from defined modes + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_gotoMode(LoRa* _LoRa, int mode){ + uint8_t read; + uint8_t data; + + read = LoRa_read(_LoRa, RegOpMode); + data = read; + + if(mode == SLEEP_MODE){ + data = (read & 0xF8) | 0x00; + _LoRa->current_mode = SLEEP_MODE; + }else if (mode == STNBY_MODE){ + data = (read & 0xF8) | 0x01; + _LoRa->current_mode = STNBY_MODE; + }else if (mode == TRANSMIT_MODE){ + data = (read & 0xF8) | 0x03; + _LoRa->current_mode = TRANSMIT_MODE; + }else if (mode == RXCONTIN_MODE){ + data = (read & 0xF8) | 0x05; + _LoRa->current_mode = RXCONTIN_MODE; + }else if (mode == RXSINGLE_MODE){ + data = (read & 0xF8) | 0x06; + _LoRa->current_mode = RXSINGLE_MODE; + } + + LoRa_write(_LoRa, RegOpMode, data); + //HAL_Delay(10); +} + + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_readReg + + description : read a register(s) by an address and a length, + then store value(s) at outpur array. + arguments : + LoRa* LoRa --> LoRa object handler + uint8_t* address --> pointer to the beginning of address array + uint16_t r_length --> detemines number of addresse bytes that + you want to send + uint8_t* output --> pointer to the beginning of output array + uint16_t w_length --> detemines number of bytes that you want to read + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_readReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* output, uint16_t w_length){ + HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_RESET); + HAL_SPI_Transmit(_LoRa->hSPIx, address, r_length, TRANSMIT_TIMEOUT); + while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) + ; + HAL_SPI_Receive(_LoRa->hSPIx, output, w_length, RECEIVE_TIMEOUT); + while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) + ; + HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_SET); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_writeReg + + description : write a value(s) in a register(s) by an address + + arguments : + LoRa* LoRa --> LoRa object handler + uint8_t* address --> pointer to the beginning of address array + uint16_t r_length --> detemines number of addresse bytes that + you want to send + uint8_t* output --> pointer to the beginning of values array + uint16_t w_length --> detemines number of bytes that you want to send + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_writeReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* values, uint16_t w_length){ + HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_RESET); + HAL_SPI_Transmit(_LoRa->hSPIx, address, r_length, TRANSMIT_TIMEOUT); + while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) + ; + HAL_SPI_Transmit(_LoRa->hSPIx, values, w_length, TRANSMIT_TIMEOUT); + while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) + ; + HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_SET); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_setFrequency + + description : set carrier frequency e.g 433 MHz + + arguments : + LoRa* LoRa --> LoRa object handler + int freq --> desired frequency in MHz unit, e.g 434 + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_setFrequency(LoRa* _LoRa, int freq){ + uint8_t data; + uint32_t F; + F = (freq * 524288)>>5; + + // write Msb: + data = F >> 16; + LoRa_write(_LoRa, RegFrMsb, data); + HAL_Delay(5); + + // write Mid: + data = F >> 8; + LoRa_write(_LoRa, RegFrMid, data); + HAL_Delay(5); + + // write Lsb: + data = F >> 0; + LoRa_write(_LoRa, RegFrLsb, data); + HAL_Delay(5); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_setSpreadingFactor + + description : set spreading factor, from 7 to 12. + + arguments : + LoRa* LoRa --> LoRa object handler + int SP --> desired spreading factor e.g 7 + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_setSpreadingFactor(LoRa* _LoRa, int SF){ + uint8_t data; + uint8_t read; + + if(SF>12) + SF = 12; + if(SF<7) + SF = 7; + + read = LoRa_read(_LoRa, RegModemConfig2); + HAL_Delay(10); + + data = (SF << 4) + (read & 0x0F); + LoRa_write(_LoRa, RegModemConfig2, data); + HAL_Delay(10); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_setPower + + description : set power gain. + + arguments : + LoRa* LoRa --> LoRa object handler + int power --> desired power like POWER_17db + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_setPower(LoRa* _LoRa, uint8_t power){ + LoRa_write(_LoRa, RegPaConfig, power); + HAL_Delay(10); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_setOCP + + description : set maximum allowed current. + + arguments : + LoRa* LoRa --> LoRa object handler + int current --> desired max currnet in mA, e.g 120 + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_setOCP(LoRa* _LoRa, uint8_t current){ + uint8_t OcpTrim = 0; + + if(current<45) + current = 45; + if(current>240) + current = 240; + + if(current <= 120) + OcpTrim = (current - 45)/5; + else if(current <= 240) + OcpTrim = (current + 30)/10; + + OcpTrim = OcpTrim + (1 << 5); + LoRa_write(_LoRa, RegOcp, OcpTrim); + HAL_Delay(10); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_setTOMsb_setCRCon + + description : set timeout msb to 0xFF + set CRC enable. + + arguments : + LoRa* LoRa --> LoRa object handler + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_setTOMsb_setCRCon(LoRa* _LoRa){ + uint8_t read, data; + + read = LoRa_read(_LoRa, RegModemConfig2); + + data = read | 0x07; + LoRa_write(_LoRa, RegModemConfig2, data);\ + HAL_Delay(10); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_read + + description : read a register by an address + + arguments : + LoRa* LoRa --> LoRa object handler + uint8_t address --> address of the register e.g 0x1D + + returns : register value +\* ----------------------------------------------------------------------------- */ +uint8_t LoRa_read(LoRa* _LoRa, uint8_t address){ + uint8_t read_data; + uint8_t data_addr; + + data_addr = address & 0x7F; + LoRa_readReg(_LoRa, &data_addr, 1, &read_data, 1); + //HAL_Delay(5); + + return read_data; +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_write + + description : write a value in a register by an address + + arguments : + LoRa* LoRa --> LoRa object handler + uint8_t address --> address of the register e.g 0x1D + uint8_t value --> value that you want to write + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_write(LoRa* _LoRa, uint8_t address, uint8_t value){ + uint8_t data; + uint8_t addr; + + addr = address | 0x80; + data = value; + LoRa_writeReg(_LoRa, &addr, 1, &data, 1); + //HAL_Delay(5); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_BurstWrite + + description : write a set of values in a register by an address respectively + + arguments : + LoRa* LoRa --> LoRa object handler + uint8_t address --> address of the register e.g 0x1D + uint8_t *value --> address of values that you want to write + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_BurstWrite(LoRa* _LoRa, uint8_t address, uint8_t *value, uint8_t length){ + uint8_t addr; + addr = address | 0x80; + + //NSS = 1 + HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_RESET); + + HAL_SPI_Transmit(_LoRa->hSPIx, &addr, 1, TRANSMIT_TIMEOUT); + while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) + ; + //Write data in FiFo + HAL_SPI_Transmit(_LoRa->hSPIx, value, length, TRANSMIT_TIMEOUT); + while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) + ; + //NSS = 0 + //HAL_Delay(5); + HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_SET); +} +/* ----------------------------------------------------------------------------- *\ + name : LoRa_isvalid + + description : check the LoRa instruct values + + arguments : + LoRa* LoRa --> LoRa object handler + + returns : returns 1 if all of the values were given, otherwise returns 0 +\* ----------------------------------------------------------------------------- */ +uint8_t LoRa_isvalid(LoRa* _LoRa){ + + return 1; +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_transmit + + description : Transmit data + + arguments : + LoRa* LoRa --> LoRa object handler + uint8_t data --> A pointer to the data you wanna send + uint8_t length --> Size of your data in Bytes + uint16_t timeOut --> Timeout in milliseconds + returns : 1 in case of success, 0 in case of timeout +\* ----------------------------------------------------------------------------- */ +uint8_t LoRa_transmit(LoRa* _LoRa, uint8_t* data, uint8_t length, uint16_t timeout){ + uint8_t read; + + int mode = _LoRa->current_mode; + LoRa_gotoMode(_LoRa, STNBY_MODE); + read = LoRa_read(_LoRa, RegFiFoTxBaseAddr); + LoRa_write(_LoRa, RegFiFoAddPtr, read); + LoRa_write(_LoRa, RegPayloadLength, length); + LoRa_BurstWrite(_LoRa, RegFiFo, data, length); + LoRa_gotoMode(_LoRa, TRANSMIT_MODE); + while(1){ + read = LoRa_read(_LoRa, RegIrqFlags); + if((read & 0x08)!=0){ + LoRa_write(_LoRa, RegIrqFlags, 0xFF); + LoRa_gotoMode(_LoRa, mode); + return 1; + } + else{ + if(--timeout==0){ + LoRa_gotoMode(_LoRa, mode); + return 0; + } + } + HAL_Delay(1); + } +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_startReceiving + + description : Start receiving continuously + + arguments : + LoRa* LoRa --> LoRa object handler + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +void LoRa_startReceiving(LoRa* _LoRa){ + LoRa_gotoMode(_LoRa, RXCONTIN_MODE); +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_Receive + + description : Read received data from module + + arguments : + LoRa* LoRa --> LoRa object handler + uint8_t data --> A pointer to the array that you want to write bytes in it + uint8_t length --> Determines how many bytes you want to read + + returns : The number of bytes received +\* ----------------------------------------------------------------------------- */ +uint8_t LoRa_receive(LoRa* _LoRa, uint8_t* data, uint8_t length){ + uint8_t read; + uint8_t number_of_bytes; + uint8_t min = 0; + + for(int i=0; i= number_of_bytes ? number_of_bytes : length; + for(int i=0; i LoRa object handler + + returns : Returns the RSSI value of last received packet. +\* ----------------------------------------------------------------------------- */ +int LoRa_getRSSI(LoRa* _LoRa){ + uint8_t read; + read = LoRa_read(_LoRa, RegPktRssiValue); + return -164 + read; +} + +/* ----------------------------------------------------------------------------- *\ + name : LoRa_init + + description : initialize and set the right setting according to LoRa sruct vars + + arguments : + LoRa* LoRa --> LoRa object handler + + returns : Nothing +\* ----------------------------------------------------------------------------- */ +uint16_t LoRa_init(LoRa* _LoRa){ + uint8_t data; + uint8_t read; + + if(LoRa_isvalid(_LoRa)){ + // goto sleep mode: + LoRa_gotoMode(_LoRa, SLEEP_MODE); + HAL_Delay(10); + + // turn on LoRa mode: + read = LoRa_read(_LoRa, RegOpMode); + HAL_Delay(10); + data = read | 0x80; + LoRa_write(_LoRa, RegOpMode, data); + HAL_Delay(100); + + // set frequency: + LoRa_setFrequency(_LoRa, _LoRa->frequency); + + // set output power gain: + LoRa_setPower(_LoRa, _LoRa->power); + + // set over current protection: + LoRa_setOCP(_LoRa, _LoRa->overCurrentProtection); + + // set LNA gain: + LoRa_write(_LoRa, RegLna, 0x23); + + // set spreading factor, CRC on, and Timeout Msb: + LoRa_setTOMsb_setCRCon(_LoRa); + LoRa_setSpreadingFactor(_LoRa, _LoRa->spredingFactor); + + // set Timeout Lsb: + LoRa_write(_LoRa, RegSymbTimeoutL, 0xFF); + + // set bandwidth, coding rate and expilicit mode: + // 8 bit RegModemConfig --> | X | X | X | X | X | X | X | X | + // bits represent --> | bandwidth | CR |I/E| + data = 0; + data = (_LoRa->bandWidth << 4) + (_LoRa->crcRate << 1); + LoRa_write(_LoRa, RegModemConfig1, data); + + // set preamble: + LoRa_write(_LoRa, RegPreambleMsb, _LoRa->preamble >> 8); + LoRa_write(_LoRa, RegPreambleLsb, _LoRa->preamble >> 0); + + // DIO mapping: --> DIO: RxDone + read = LoRa_read(_LoRa, RegDioMapping1); + data = read | 0x3F; + LoRa_write(_LoRa, RegDioMapping1, data); + + // goto standby mode: + LoRa_gotoMode(_LoRa, STNBY_MODE); + _LoRa->current_mode = STNBY_MODE; + HAL_Delay(10); + + read = LoRa_read(_LoRa, RegVersion); + if(read == 0x12) + return LORA_OK; + else + return LORA_NOT_FOUND; + } + else { + return LORA_UNAVAILABLE; + } +} \ No newline at end of file diff --git a/LoRa/LoRa.h b/LoRa/LoRa.h new file mode 100644 index 0000000..3d34af3 --- /dev/null +++ b/LoRa/LoRa.h @@ -0,0 +1,129 @@ +// -------------------------------------------------- \\ +// | | \\ +// | WRITTEN BY: Sslman Motlaq | \\ +// | Telegram: @S_Motlaq | \\ +// | E-MAIL: motlaq@aut.ac.ir | \\ +// | | \\ +// -------------------------------------------------- // + +#include "main.h" + +#define TRANSMIT_TIMEOUT 2000 +#define RECEIVE_TIMEOUT 2000 + +//--------- MODES ---------// +#define SLEEP_MODE 0 +#define STNBY_MODE 1 +#define TRANSMIT_MODE 3 +#define RXCONTIN_MODE 5 +#define RXSINGLE_MODE 6 + +//------- BANDWIDTH -------// +#define BW_7_8KHz 0 +#define BW_10_4KHz 1 +#define BW_15_6KHz 2 +#define BW_20_8KHz 3 +#define BW_31_25KHz 4 +#define BW_41_7KHz 5 +#define BW_62_5KHz 6 +#define BW_125KHz 7 +#define BW_250KHz 8 +#define BW_500KHz 9 + +//------ CODING RATE ------// +#define CR_4_5 1 +#define CR_4_6 2 +#define CR_4_7 3 +#define CR_4_8 4 + +//--- SPREADING FACTORS ---// +#define SF_7 7 +#define SF_8 8 +#define SF_9 9 +#define SF_10 10 +#define SF_11 11 +#define SF_12 12 + +//------ POWER GAIN ------// +#define POWER_11db 0xF6 +#define POWER_14db 0xF9 +#define POWER_17db 0xFC +#define POWER_20db 0xFF + +//------- REGISTERS -------// +#define RegFiFo 0x00 +#define RegOpMode 0x01 +#define RegFrMsb 0x06 +#define RegFrMid 0x07 +#define RegFrLsb 0x08 +#define RegPaConfig 0x09 +#define RegOcp 0x0B +#define RegLna 0x0C +#define RegFiFoAddPtr 0x0D +#define RegFiFoTxBaseAddr 0x0E +#define RegFiFoRxBaseAddr 0x0F +#define RegFiFoRxCurrentAddr 0x10 +#define RegIrqFlags 0x12 +#define RegRxNbBytes 0x13 +#define RegPktRssiValue 0x1A +#define RegModemConfig1 0x1D +#define RegModemConfig2 0x1E +#define RegSymbTimeoutL 0x1F +#define RegPreambleMsb 0x20 +#define RegPreambleLsb 0x21 +#define RegPayloadLength 0x22 +#define RegDioMapping1 0x40 +#define RegDioMapping2 0x41 +#define RegVersion 0x42 + +//------ LORA STATUS ------// +#define LORA_OK 200 +#define LORA_NOT_FOUND 404 +#define LORA_LARGE_PAYLOAD 413 +#define LORA_UNAVAILABLE 503 + +typedef struct LoRa_setting{ + + // Hardware setings: + GPIO_TypeDef* CS_port; + uint16_t CS_pin; + GPIO_TypeDef* reset_port; + uint16_t reset_pin; + GPIO_TypeDef* DIO0_port; + uint16_t DIO0_pin; + SPI_HandleTypeDef* hSPIx; + + // Module settings: + int current_mode; + int frequency; + uint8_t spredingFactor; + uint8_t bandWidth; + uint8_t crcRate; + uint16_t preamble; + uint8_t power; + uint8_t overCurrentProtection; + +} LoRa; + +LoRa newLoRa(void); +void LoRa_reset(LoRa* _LoRa); +void LoRa_readReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* output, uint16_t w_length); +void LoRa_writeReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* values, uint16_t w_length); +void LoRa_gotoMode(LoRa* _LoRa, int mode); +uint8_t LoRa_read(LoRa* _LoRa, uint8_t address); +void LoRa_write(LoRa* _LoRa, uint8_t address, uint8_t value); +void LoRa_BurstWrite(LoRa* _LoRa, uint8_t address, uint8_t *value, uint8_t length); +uint8_t LoRa_isvalid(LoRa* _LoRa); + +void LoRa_setFrequency(LoRa* _LoRa, int freq); +void LoRa_setSpreadingFactor(LoRa* _LoRa, int SP); +void LoRa_setPower(LoRa* _LoRa, uint8_t power); +void LoRa_setOCP(LoRa* _LoRa, uint8_t current); +void LoRa_setTOMsb_setCRCon(LoRa* _LoRa); +uint8_t LoRa_transmit(LoRa* _LoRa, uint8_t* data, uint8_t length, uint16_t timeout); +void LoRa_startReceiving(LoRa* _LoRa); +uint8_t LoRa_receive(LoRa* _LoRa, uint8_t* data, uint8_t length); +void LoRa_receive_IT(LoRa* _LoRa, uint8_t* data, uint8_t length); +int LoRa_getRSSI(LoRa* _LoRa); + +uint16_t LoRa_init(LoRa* _LoRa); \ No newline at end of file From 1587d7faacc8c08827e8a68d29f41e2c963a1a1b Mon Sep 17 00:00:00 2001 From: niekky Date: Tue, 12 Dec 2023 16:57:12 -0700 Subject: [PATCH 02/60] Added correct LoRa module drivers --- lora_sx1276/LoRa.c | 649 +++++++++++++++++++++++++++++++++++++++++++++ lora_sx1276/LoRa.h | 391 +++++++++++++++++++++++++++ 2 files changed, 1040 insertions(+) create mode 100644 lora_sx1276/LoRa.c create mode 100644 lora_sx1276/LoRa.h diff --git a/lora_sx1276/LoRa.c b/lora_sx1276/LoRa.c new file mode 100644 index 0000000..ced81d4 --- /dev/null +++ b/lora_sx1276/LoRa.c @@ -0,0 +1,649 @@ +// Copyright (c) Konstantin Belyalov. All rights reserved. +// Licensed under the MIT license. +#include "LoRa.h" + +// Debugging support +// To enable debug information add +// #define LORA_DEBUG +// to main.h +#ifdef LORA_DEBUG +#define DEBUGF(msg, ...) printf(const char *fmt, ##__VA_ARGS__); +#else +#define DEBUGF(msg, ...) +#endif + +// SPI helpers // + +// Reads single register +static uint8_t read_register(lora_sx1276 *lora, uint8_t address) +{ + uint8_t value = 0; + + // 7bit controls read/write mode + CLEAR_BIT(address, BIT_7); + + // Start SPI transaction + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); + // Transmit reg address, then receive it value + uint32_t res1 = HAL_SPI_Transmit(lora->spi, &address, 1, lora->spi_timeout); + uint32_t res2 = HAL_SPI_Receive(lora->spi, &value, 1, lora->spi_timeout); + // End SPI transaction + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); + + if (res1 != HAL_OK || res2 != HAL_OK) { + DEBUGF("SPI transmit/receive failed (%d %d)", res1, res2); + } + + return value; +} + +// Writes single register +static void write_register(lora_sx1276 *lora, uint8_t address, uint8_t value) +{ + // 7bit controls read/write mode + SET_BIT(address, BIT_7); + + // Reg address + its new value + uint16_t payload = (value << 8) | address; + + // Start SPI transaction, send address + value + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); + uint32_t res = HAL_SPI_Transmit(lora->spi, (uint8_t*)&payload, 2, lora->spi_timeout); + // End SPI transaction + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); + + if (res != HAL_OK) { + DEBUGF("SPI transmit failed: %d", res); + } +} + +// Copies bytes from buffer into radio FIFO given len length +static void write_fifo(lora_sx1276 *lora, uint8_t *buffer, uint8_t len, uint8_t mode) +{ + uint8_t address = REG_FIFO | BIT_7; + + // Start SPI transaction, send address + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); + uint32_t res1 = HAL_SPI_Transmit(lora->spi, &address, 1, lora->spi_timeout); + if (mode == TRANSFER_MODE_DMA) { + HAL_SPI_Transmit_DMA(lora->spi, buffer, len); + // Intentionally leave SPI active - let DMA finish transfer + return; + } + uint32_t res2 = HAL_SPI_Transmit(lora->spi, buffer, len, lora->spi_timeout); + // End SPI transaction + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); + + if (res1 != HAL_OK || res2 != HAL_OK) { + DEBUGF("SPI transmit failed"); + } +} + +// Reads data "len" size from FIFO into buffer +static void read_fifo(lora_sx1276 *lora, uint8_t *buffer, uint8_t len, uint8_t mode) +{ + uint8_t address = REG_FIFO; + + // Start SPI transaction, send address + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); + uint32_t res1 = HAL_SPI_Transmit(lora->spi, &address, 1, lora->spi_timeout); + uint32_t res2; + if (mode == TRANSFER_MODE_DMA) { + res2 = HAL_SPI_Receive_DMA(lora->spi, buffer, len); + // Do not end SPI here - must be done externally when DMA done + } else { + res2 = HAL_SPI_Receive(lora->spi, buffer, len, lora->spi_timeout); + // End SPI transaction + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); + } + + if (res1 != HAL_OK || res2 != HAL_OK) { + DEBUGF("SPI receive/transmit failed"); + } +} + +static void set_mode(lora_sx1276 *lora, uint8_t mode) +{ + write_register(lora, REG_OP_MODE, OPMODE_LONG_RANGE_MODE | mode); +} + +// Set Overload Current Protection +static void set_OCP(lora_sx1276 *lora, uint8_t imax) +{ + uint8_t value; + + // Minimum available current is 45mA, maximum 240mA + // As per page 80 of datasheet + if (imax < 45) { + imax = 45; + } + if (imax > 240) { + imax = 240; + } + + if (imax < 130) { + value = (imax - 45) / 5; + } else { + value = (imax + 30) / 10; + } + + write_register(lora, REG_OCP, OCP_ON | value); +} + +static void set_low_data_rate_optimization(lora_sx1276 *lora) +{ + assert_param(lora); + + // Read current signal bandwidth + uint64_t bandwidth = read_register(lora, REG_MODEM_CONFIG_1) >> 4; + // Read current spreading factor + uint8_t sf = read_register(lora, REG_MODEM_CONFIG_2) >> 4; + + uint8_t mc3 = MC3_AGCAUTO; + + if (sf >= 11 && bandwidth == LORA_BANDWIDTH_125_KHZ) { + mc3 |= MC3_MOBILE_NODE; + } + + write_register(lora, REG_MODEM_CONFIG_3, mc3); +} + +void lora_mode_sleep(lora_sx1276 *lora) +{ + assert_param(lora); + + set_mode(lora, OPMODE_SLEEP); +} + +void lora_mode_receive_continuous(lora_sx1276 *lora) +{ + assert_param(lora); + + // Update base FIFO address for incoming packets + write_register(lora, REG_FIFO_RX_BASE_ADDR, lora->rx_base_addr); + // Clear all RX related IRQs + write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); + + set_mode(lora, OPMODE_RX_CONTINUOUS); +} + +void lora_mode_receive_single(lora_sx1276 *lora) +{ + assert_param(lora); + + // Update base FIFO address for incoming packets + write_register(lora, REG_FIFO_RX_BASE_ADDR, lora->rx_base_addr); + // Clear all RX related IRQs + write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); + + set_mode(lora, OPMODE_RX_SINGLE); +} + +void lora_mode_standby(lora_sx1276 *lora) +{ + assert_param(lora); + + set_mode(lora, OPMODE_STDBY); +} + +void lora_set_implicit_header_mode(lora_sx1276 *lora) +{ + assert_param(lora); + + uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); + mc1 |= MC1_IMPLICIT_HEADER_MODE; + write_register(lora, REG_MODEM_CONFIG_1, mc1); +} + +void lora_set_explicit_header_mode(lora_sx1276 *lora) +{ + assert_param(lora); + + uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); + mc1 &= ~MC1_IMPLICIT_HEADER_MODE; + write_register(lora, REG_MODEM_CONFIG_1, mc1); +} + +void lora_set_tx_power(lora_sx1276 *lora, uint8_t level) +{ + assert_param(lora); + + if (lora->pa_mode == LORA_PA_OUTPUT_RFO) { + // RFO pin + assert_param(level <= 15); + if (level > 15) { + level = 15; + } + // 7 bit -> PaSelect: 0 for RFO --- = 0x70 + // 6-4 bits -> MaxPower (select all) --^ + // 3-0 bits -> Output power, dB (max 15) + write_register(lora, REG_PA_CONFIG, 0x70 | level); + } else { + // PA BOOST pin, from datasheet (Power Amplifier): + // Pout=17-(15-OutputPower) + assert_param(level <= 20 && level >= 2); + if (level > 20) { + level = 20; + } + if (level < 2) { + level = 2; + } + // Module power consumption from datasheet: + // RFOP = +20 dBm, on PA_BOOST -> 120mA + // RFOP = +17 dBm, on PA_BOOST -> 87mA + if (level > 17) { + // PA_DAC_HIGH_POWER operation changes last 3 OutputPower modes to: + // 13 -> 18dB, 14 -> 19dB, 15 -> 20dB + // So subtract 3 from level + level -= 3; + // Enable High Power mode + write_register(lora, REG_PA_DAC, PA_DAC_HIGH_POWER); + // Limit maximum current to 140mA (+20mA to datasheet value to be sure) + set_OCP(lora, 140); + } else { + // Enable half power mode (default) + write_register(lora, REG_PA_DAC, PA_DAC_HALF_POWER); + // Limit maximum current to 97mA (+10mA to datasheet value to be sure) + set_OCP(lora, 97); + } + // Minimum power level is 2 which is 0 for chip + level -= 2; + // 7 bit -> PaSelect: 1 for PA_BOOST + write_register(lora, REG_PA_CONFIG, BIT_7 | level); + } +} + +void lora_set_frequency(lora_sx1276 *lora, uint64_t freq) +{ + assert_param(lora); + + // From datasheet: FREQ = (FRF * 32 Mhz) / (2 ^ 19) + uint64_t frf = (freq << 19) / (32 * MHZ); + + write_register(lora, REG_FRF_MSB, frf >> 16); + write_register(lora, REG_FRF_MID, (frf & 0xff00) >> 8); + write_register(lora, REG_FRF_LSB, frf & 0xff); +} + +int8_t lora_packet_rssi(lora_sx1276 *lora) +{ + assert_param(lora); + + uint8_t rssi = read_register(lora, REG_PKT_RSSI_VALUE); + + return lora->frequency < (868 * MHZ) ? rssi - 164 : rssi - 157; +} + +uint8_t lora_packet_snr(lora_sx1276 *lora) +{ + assert_param(lora); + + uint8_t snr = read_register(lora, REG_PKT_SNR_VALUE); + + return snr / 5; +} + +void lora_set_signal_bandwidth(lora_sx1276 *lora, uint64_t bw) +{ + assert_param(lora && bw < LORA_BW_LAST); + + // REG_MODEM_CONFIG_1 has 2 more parameters: + // Coding rate / Header mode, so read them before set bandwidth + uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); + // Signal bandwidth uses 4-7 bits of config + mc1 = (mc1 & 0x0F) | bw << 4; + write_register(lora, REG_MODEM_CONFIG_1, mc1); + + set_low_data_rate_optimization(lora); +} + +void lora_set_spreading_factor(lora_sx1276 *lora, uint8_t sf) +{ + assert_param(lora && sf <= 12 && sf >=6); + + if (sf < 6) { + sf = 6; + } else if (sf > 12) { + sf = 12; + } + + if (sf == 6) { + write_register(lora, REG_DETECTION_OPTIMIZE, 0xc5); + write_register(lora, REG_DETECTION_THRESHOLD, 0x0c); + } else { + write_register(lora, REG_DETECTION_OPTIMIZE, 0xc3); + write_register(lora, REG_DETECTION_THRESHOLD, 0x0a); + } + // Set new spread factor + uint8_t mc2 = read_register(lora, REG_MODEM_CONFIG_2); + mc2 = (mc2 & 0x0F) | (sf << 4); + // uint8_t new_config = (current_config & 0x0f) | ((sf << 4) & 0xf0); + write_register(lora, REG_MODEM_CONFIG_2, mc2); + + set_low_data_rate_optimization(lora); +} + +void lora_set_crc(lora_sx1276 *lora, uint8_t enable) +{ + assert_param(lora); + + uint8_t mc2 = read_register(lora, REG_MODEM_CONFIG_2); + + if (enable) { + mc2 |= MC2_CRC_ON; + } else { + mc2 &= ~MC2_CRC_ON; + } + + write_register(lora, REG_MODEM_CONFIG_2, mc2); +} + +void lora_set_coding_rate(lora_sx1276 *lora, uint8_t rate) +{ + assert_param(lora); + + uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); + + // coding rate bits are 1-3 in modem config 1 register + mc1 |= rate << 1; + write_register(lora, REG_MODEM_CONFIG_1, mc1); +} + +void lora_set_preamble_length(lora_sx1276 *lora, uint16_t len) +{ + assert_param(lora); + + write_register(lora, REG_PREAMBLE_MSB, len >> 8); + write_register(lora, REG_PREAMBLE_LSB, len & 0xf); +} + +uint8_t lora_version(lora_sx1276 *lora) +{ + assert_param(lora); + + return read_register(lora, REG_VERSION); +} + +uint8_t lora_is_transmitting(lora_sx1276 *lora) +{ + assert_param(lora); + + uint8_t opmode = read_register(lora, REG_OP_MODE); + + return (opmode & OPMODE_TX) == OPMODE_TX ? LORA_BUSY : LORA_OK; +} + +static uint8_t lora_send_packet_base(lora_sx1276 *lora, uint8_t *data, uint8_t data_len, uint8_t mode) +{ + assert_param(lora && data && data_len > 0); + + if (lora_is_transmitting(lora)) { + return LORA_BUSY; + } + + // Wakeup radio because of FIFO is only available in STANDBY mode + set_mode(lora, OPMODE_STDBY); + + // Clear TX IRQ flag, to be sure + lora_clear_interrupt_tx_done(lora); + + // Set FIFO pointer to the beginning of the buffer + write_register(lora, REG_FIFO_ADDR_PTR, lora->tx_base_addr); + write_register(lora, REG_FIFO_TX_BASE_ADDR, lora->tx_base_addr); + write_register(lora, REG_PAYLOAD_LENGTH, data_len); + + // Copy packet into radio FIFO + write_fifo(lora, data, data_len, mode); + if (mode == TRANSFER_MODE_DMA) { + return LORA_OK; + } + + // Put radio in TX mode - packet will be transmitted ASAP + set_mode(lora, OPMODE_TX); + return LORA_OK; +} + +uint8_t lora_send_packet(lora_sx1276 *lora, uint8_t *data, uint8_t data_len) +{ + return lora_send_packet_base(lora, data, data_len, TRANSFER_MODE_BLOCKING); +} + +uint8_t lora_send_packet_dma_start(lora_sx1276 *lora, uint8_t *data, uint8_t data_len) +{ + return lora_send_packet_base(lora, data, data_len, TRANSFER_MODE_DMA); +} + +// Finish packet send initiated by lora_send_packet_dma_start() +void lora_send_packet_dma_complete(lora_sx1276 *lora) +{ + // End transfer + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); + // Send packet + set_mode(lora, OPMODE_TX); +} + +uint8_t lora_send_packet_blocking(lora_sx1276 *lora, uint8_t *data, uint8_t data_len, uint32_t timeout) +{ + assert_param(lora && data && data_len > 0 && timeout > 0); + + uint8_t res = lora_send_packet(lora, data, data_len); + + if (res == LORA_OK) { + // Wait until packet gets transmitted + uint32_t elapsed = 0; + while (elapsed < timeout) { + uint8_t state = read_register(lora, REG_IRQ_FLAGS); + if (state & IRQ_FLAGS_TX_DONE) { + // Packet sent + write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_TX_DONE); + return LORA_OK; + } + HAL_Delay(1); + elapsed++; + } + } + + return LORA_TIMEOUT; +} + +void lora_set_rx_symbol_timeout(lora_sx1276 *lora, uint16_t symbols) +{ + assert_param(lora && symbols <= 1024 && symbols >= 4); + + if (symbols < 4) { + symbols = 4; + } + if (symbols > 1023) { + symbols = 1024; + } + + write_register(lora, REG_SYMB_TIMEOUT_LSB, symbols & 0xf); + if (symbols > 255) { + // MSB (2 first bits of config2) + uint8_t mc2 = read_register(lora, REG_MODEM_CONFIG_2); + mc2 |= symbols >> 8; + write_register(lora, REG_MODEM_CONFIG_2, mc2); + } +} + +uint8_t lora_is_packet_available(lora_sx1276 *lora) +{ + assert_param(lora); + + uint8_t irqs = read_register(lora, REG_IRQ_FLAGS); + + // In case of Single receive mode RX_TIMEOUT will be issued + return irqs & (IRQ_FLAGS_RX_DONE | IRQ_FLAGS_RX_TIMEOUT); +} + +uint8_t lora_pending_packet_length(lora_sx1276 *lora) +{ + uint8_t len; + + // Query for current header mode - implicit / explicit + uint8_t implicit = read_register(lora, REG_MODEM_CONFIG_1) & MC1_IMPLICIT_HEADER_MODE; + if (implicit) { + len = read_register(lora, REG_PAYLOAD_LENGTH); + } else { + len = read_register(lora, REG_RX_NB_BYTES); + } + + return len; +} + + +static uint8_t lora_receive_packet_base(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error, uint8_t mode) +{ + assert_param(lora && buffer && buffer_len > 0); + + uint8_t res = LORA_EMPTY; + uint8_t len = 0; + + // Read/Reset IRQs + uint8_t state = read_register(lora, REG_IRQ_FLAGS); + write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); + + if (state & IRQ_FLAGS_RX_TIMEOUT) { + DEBUGF("timeout"); + res = LORA_TIMEOUT; + goto done; + } + + if (state & IRQ_FLAGS_RX_DONE) { + if (!(state & IRQ_FLAGS_VALID_HEADER)) { + DEBUGF("invalid header"); + res = LORA_INVALID_HEADER; + goto done; + } + // Packet has been received + if (state & IRQ_FLAGS_PAYLOAD_CRC_ERROR) { + DEBUGF("CRC error"); + res = LORA_CRC_ERROR; + goto done; + } + // Query for current header mode - implicit / explicit + len = lora_pending_packet_length(lora); + // Set FIFO to beginning of the packet + uint8_t offset = read_register(lora, REG_FIFO_RX_CURRENT_ADDR); + write_register(lora, REG_FIFO_ADDR_PTR, offset); + // Read payload + read_fifo(lora, buffer, len, mode); + res = LORA_OK; + } + +done: + if (error) { + *error = res; + } + + return len; +} + +uint8_t lora_receive_packet(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error) +{ + return lora_receive_packet_base(lora, buffer, buffer_len, error, TRANSFER_MODE_BLOCKING); +} + +uint8_t lora_receive_packet_dma_start(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error) +{ + return lora_receive_packet_base(lora, buffer, buffer_len, error, TRANSFER_MODE_DMA); +} + +void lora_receive_packet_dma_complete(lora_sx1276 *lora) +{ + // Nothing to do expect - just end SPI transaction + HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); +} + +uint8_t lora_receive_packet_blocking(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, + uint32_t timeout, uint8_t *error) +{ + assert_param(lora && buffer && buffer_len > 0); + + uint32_t elapsed = 0; + + // Wait up to timeout for packet + while (elapsed < timeout) { + if (lora_is_packet_available(lora)) { + break; + } + HAL_Delay(1); + elapsed++; + } + + return lora_receive_packet(lora, buffer, buffer_len, error); +} + +void lora_enable_interrupt_rx_done(lora_sx1276 *lora) +{ + // Table 63 DIO Mapping LoRaTM Mode: + // 00 -> (DIO0 rx_done) + // DIO0 uses 6-7 bits of DIO_MAPPING_1 + write_register(lora, REG_DIO_MAPPING_1, 0x00); +} + +void lora_enable_interrupt_tx_done(lora_sx1276 *lora) +{ + // Table 63 DIO Mapping LoRaTM Mode: + // 01 -> (DIO0 tx_done) + // DIO0 uses 6-7 bits of DIO_MAPPING_1 + write_register(lora, REG_DIO_MAPPING_1, 0x40); +} + +void lora_clear_interrupt_tx_done(lora_sx1276 *lora) +{ + write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_TX_DONE); +} + +void lora_clear_interrupt_rx_all(lora_sx1276 *lora) +{ + write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); +} + + +uint8_t lora_init(lora_sx1276 *lora, SPI_HandleTypeDef *spi, GPIO_TypeDef *nss_port, + uint16_t nss_pin, uint64_t freq) +{ + assert_param(lora && spi); + + // Init params with default values + lora->spi = spi; + lora->nss_port = nss_port; + lora->nss_pin = nss_pin; + lora->frequency = freq; + lora->pa_mode = LORA_PA_OUTPUT_PA_BOOST; + lora->tx_base_addr = LORA_DEFAULT_TX_ADDR; + lora->rx_base_addr = LORA_DEFAULT_RX_ADDR; + lora->spi_timeout = LORA_DEFAULT_SPI_TIMEOUT; + + // Check version + uint8_t ver = lora_version(lora); + if (ver != LORA_COMPATIBLE_VERSION) { + DEBUGF("Got wrong radio version 0x%x, expected 0x12", ver); + return LORA_ERROR; + } + + // Modem parameters (freq, mode, etc) must be done in SLEEP mode. + lora_mode_sleep(lora); + // Enable LoRa mode (since it can be switched on only in sleep) + lora_mode_sleep(lora); + + // Set frequency + lora_set_frequency(lora, freq); + lora_set_spreading_factor(lora, LORA_DEFAULT_SF); + lora_set_preamble_length(lora, LORA_DEFAULT_PREAMBLE_LEN); + // By default - explicit header mode + lora_set_explicit_header_mode(lora); + // Set LNA boost + uint8_t current_lna = read_register(lora, REG_LNA); + write_register(lora, REG_LNA, current_lna | 0x03); + // Set auto AGC + write_register(lora, REG_MODEM_CONFIG_3, 0x04); + // Set default output power + lora_set_tx_power(lora, LORA_DEFAULT_TX_POWER); + // Set default mode + lora_mode_standby(lora); + + return LORA_OK; +} + diff --git a/lora_sx1276/LoRa.h b/lora_sx1276/LoRa.h new file mode 100644 index 0000000..ea96125 --- /dev/null +++ b/lora_sx1276/LoRa.h @@ -0,0 +1,391 @@ +// Copyright (c) Konstantin Belyalov. All rights reserved. +// Licensed under the MIT license. + +#ifndef __LORA_H +#define __LORA_H + +#include "main.h" + + +// sx1276 registers +#define REG_FIFO 0x00 +#define REG_OP_MODE 0x01 +#define REG_FRF_MSB 0x06 +#define REG_FRF_MID 0x07 +#define REG_FRF_LSB 0x08 +#define REG_PA_CONFIG 0x09 +#define REG_OCP 0x0b +#define REG_LNA 0x0c +#define REG_FIFO_ADDR_PTR 0x0d +#define REG_FIFO_TX_BASE_ADDR 0x0e +#define REG_FIFO_RX_BASE_ADDR 0x0f +#define REG_FIFO_RX_CURRENT_ADDR 0x10 +#define REG_IRQ_FLAGS 0x12 +#define REG_RX_NB_BYTES 0x13 +#define REG_PKT_SNR_VALUE 0x19 +#define REG_PKT_RSSI_VALUE 0x1a +#define REG_MODEM_CONFIG_1 0x1d +#define REG_MODEM_CONFIG_2 0x1e +#define REG_SYMB_TIMEOUT_LSB 0x1f +#define REG_PREAMBLE_MSB 0x20 +#define REG_PREAMBLE_LSB 0x21 +#define REG_PAYLOAD_LENGTH 0x22 +#define REG_MODEM_CONFIG_3 0x26 +#define REG_DETECTION_OPTIMIZE 0x31 +#define REG_DETECTION_THRESHOLD 0x37 +#define REG_DIO_MAPPING_1 0x40 +#define REG_VERSION 0x42 +#define REG_PA_DAC 0x4d + +// modes +#define OPMODE_SLEEP 0x00 +#define OPMODE_STDBY 0x01 +#define OPMODE_TX 0x03 +#define OPMODE_RX_CONTINUOUS 0x05 +#define OPMODE_RX_SINGLE 0x06 +#define OPMODE_LONG_RANGE_MODE 0x80 // (1 << 7) + +// Power Amplifier (PA_DAC) settings +#define PA_DAC_HIGH_POWER 0x87 +#define PA_DAC_HALF_POWER 0x84 + +// Over Current Protection (OCP) config +#define OCP_ON (1 << 5) + +// Modem config register parameters +#define MC1_IMPLICIT_HEADER_MODE (1 << 0) + +#define MC2_CRC_ON (1 << 2) + +#define MC3_AGCAUTO (1 << 2) +#define MC3_MOBILE_NODE (1 << 3) + +// IRQs +#define IRQ_FLAGS_RX_TIMEOUT (1 << 7) +#define IRQ_FLAGS_RX_DONE (1 << 6) +#define IRQ_FLAGS_PAYLOAD_CRC_ERROR (1 << 5) +#define IRQ_FLAGS_VALID_HEADER (1 << 4) +#define IRQ_FLAGS_TX_DONE (1 << 3) +#define IRQ_FLAGS_CAD_DONE (1 << 2) +#define IRQ_FLAGS_FHSSCHANGECHANNEL (1 << 1) +#define IRQ_FLAGS_CAD_DETECTED (1 << 0) +#define IRQ_FLAGS_RX_ALL 0xf0 + +// Just to make it readable +#define BIT_7 (1 << 7) + +#define TRANSFER_MODE_DMA 1 +#define TRANSFER_MODE_BLOCKING 2 + + + +/* LORA SETTING CONFIGURATION */ + +#define LORA_MAX_PACKET_SIZE 128 + +// Operational frequency +#define MHZ 1000000LLU +#define LORA_BASE_FREQUENCY_US (915LLU*MHZ) +#define LORA_BASE_FREQUENCY_EU (868LLU*MHZ) + +// Default settings +#define LORA_DEFAULT_TX_POWER 17 +#define LORA_DEFAULT_SF 7 +#define LORA_DEFAULT_PREAMBLE_LEN 10 +#define LORA_DEFAULT_RX_ADDR 0 +#define LORA_DEFAULT_TX_ADDR 0 +#define LORA_DEFAULT_SPI_TIMEOUT 1000 // ms + +#define LORA_COMPATIBLE_VERSION 0x12U + +// LORA return codes +#define LORA_OK 0 +#define LORA_CRC_ERROR 1 +#define LORA_TIMEOUT 2 +#define LORA_INVALID_HEADER 3 +#define LORA_ERROR 4 +#define LORA_BUSY 5 +#define LORA_EMPTY 6 + +// TX power mode select +#define LORA_PA_OUTPUT_RFO 0 +#define LORA_PA_OUTPUT_PA_BOOST 1 + +// Coding rate +#define LORA_CODING_RATE_4_5 0x08 +#define LORA_CODING_RATE_4_6 0x10 +#define LORA_CODING_RATE_4_7 0x18 +#define LORA_CODING_RATE_4_8 0x20 + +// Signal bandwidth ("spread factor") +enum { + LORA_BANDWIDTH_7_8_KHZ = 0, + LORA_BANDWIDTH_10_4_KHZ, + LORA_BANDWIDTH_15_6_KHZ, + LORA_BANDWIDTH_20_8_KHZ, + LORA_BANDWIDTH_31_25_KHZ, + LORA_BANDWIDTH_41_7_KHZ, + LORA_BANDWIDTH_62_5_KHZ, + LORA_BANDWIDTH_125_KHZ, // default SF - 7 + LORA_BANDWIDTH_250_KHZ, + LORA_BANDWIDTH_500_KHZ, + LORA_BW_LAST, +}; + +// LORA definition +typedef struct { + // SPI parameters + SPI_HandleTypeDef *spi; + GPIO_TypeDef *nss_port; + uint32_t spi_timeout; + // Operating frequency, in Hz + uint32_t frequency; + // Output PIN (module internal, not related to your design) + // Can be one of PA_OUTPUT_PA_BOOST / PA_OUTPUT_RFO + uint32_t pa_mode; + // Base FIFO addresses for RX/TX + uint8_t tx_base_addr; + uint8_t rx_base_addr; + + uint16_t nss_pin; +} lora_sx1276; + + +// LORA Module setup // + +// Initialize LORA with default parameters: +// Params: +// - `lora` LoRa definition to be initialized +// - `spi` SPI HAL bus (`hspi1`, `hspi2`, etc) +// - `nss_port` - GPIO port where `NSS` pin connected to +// - `nss_pin` - GPIO pin number in `nss_port` +// - `freq` - operating frequency. In Hz +// Returns: +// - `LORA_OK` - modem initialized successfully +// - `LORA_ERROR` - initialization failed (e.g. no modem present on SPI bus / wrong NSS port/pin) +uint8_t lora_init(lora_sx1276 *lora, SPI_HandleTypeDef *spi, GPIO_TypeDef *nss_port, + uint16_t nss_pin, uint64_t freq); + +// Returns LoRa modem version number (usually 0x12) +uint8_t lora_version(lora_sx1276 *lora); + + +// LORA mode selection // + +// Put radio into SLEEP mode: +// In this mode only SPI and configuration registers are accessible. +// LoRa FIFO is not accessible. +void lora_mode_sleep(lora_sx1276 *lora); + +// Put radio into standby (idle) mode: +// Both Crystal Oscillator and LoRa baseband blocks are turned on. +// RF part and PLLs are disabled. +void lora_mode_standby(lora_sx1276 *lora); + +// Put radio into continuous receive mode: +// When activated the RFM95/96/97/98(W) powers all remaining blocks required for reception, +// processing all received data until a new user request is made to change operating mode. +void lora_mode_receive_continuous(lora_sx1276 *lora); + +// Put radio into single receive mode: +// When activated the RFM95/96/97/98(W) powers all remaining blocks required for reception, remains in +// this state until a valid packet has been received and then returns to Standby mode. +void lora_mode_receive_single(lora_sx1276 *lora); + + +// LORA signal / transmission parameters // + +// Sets LoRa transmit power. +// Params: +// - `level` - TX power in dBm. Valid range from 2dBm to 20dBm +void lora_set_tx_power(lora_sx1276 *lora, uint8_t level); + +// Set operational frequency. +// Params: +// - `freq` - frequency in Hz +void lora_set_frequency(lora_sx1276 *lora, uint64_t freq); + +// Set signal bandwidth. +// Params: +// - `bw` - desired bandwidth, from LORA_BANDWIDTH_7_8_KHZ to LORA_BANDWIDTH_500_KHZ +// For more information refer to section 4.1 of datasheet. +void lora_set_signal_bandwidth(lora_sx1276 *lora, uint64_t bw); + +// Set signal spreading factor. +// Params: +// - `sf` - spreading factor. Value from 6 to 12 +// For more information refer to section 4.1 of datasheet. +void lora_set_spreading_factor(lora_sx1276 *lora, uint8_t sf); + +// Set coding rate. +// - `rate` - coding rate. Use any of LORA_CODING_RATE* constants. +// For more information refer to section 4.1 of datasheet. +void lora_set_coding_rate(lora_sx1276 *lora, uint8_t rate); + +// Enable / disable CRC +// Params: +// - `enable` - set to 0 to disable CRC, any other value enables CRC. +void lora_set_crc(lora_sx1276 *lora, uint8_t enable); + +// Set length of packet preamble. +// Params: +// - `len` - length of packet preamble +// For more information refer to section 4.1.1.6 of datasheet +void lora_set_preamble_length(lora_sx1276 *lora, uint16_t len); + +// Set "implicit header" mode, meaning no packet header at all. +// Refer to section 4.1.1.6 of datasheet +void lora_set_implicit_header_mode(lora_sx1276 *lora); + +// Set "explicit", i.e. always add packet header with various system information. +// Refer to section 4.1.1.6 of datasheet +void lora_set_explicit_header_mode(lora_sx1276 *lora); + + +// Received packet information // + +// Returns RSSI of last received packet +int8_t lora_packet_rssi(lora_sx1276 *lora); + +// Returns SNR of last received packet +uint8_t lora_packet_snr(lora_sx1276 *lora); + + +// SEND packet routines // + +// Query modem for any ongoing packet transmission. +// Returns 0 if no active transmission present +uint8_t lora_is_transmitting(lora_sx1276 *lora); + +// Send packet in non-blocking mode +// Params: +// - `data` - pointer to buffer to be transmitted +// - `data_len` - how many bytes to transmit from `data` buffer. +// Returns: +// - `LORA_BUSY` in case of active transmission ongoing +// - `LORA_OK` packet scheduled to be sent. +// Check state with `lora_is_transmitting()` or by interrupt. +uint8_t lora_send_packet(lora_sx1276 *lora, uint8_t *data, uint8_t data_len); + +// Send packet using DMA mode. +// You must call lora_send_packet_dma_complete() from DMA transfer complete callback +// Params: +// - `data` - pointer to buffer to be transmitted +// - `data_len` - how many bytes to transmit from `data` buffer. +// Returns: +// - `LORA_BUSY` in case of active transmission ongoing +// - `LORA_TIMEOUT` packet wasn't transmitted in given time frame. +// - `LORA_OK` packet scheduled to be sent. +uint8_t lora_send_packet_dma_start(lora_sx1276 *lora, uint8_t *data, uint8_t data_len); + +// Finish packet send initiated by lora_send_packet_dma_start() +void lora_send_packet_dma_complete(lora_sx1276 *lora); + +// Send packet and returns only when packet sent / error occurred (blocking mode). +// Params: +// - `data` - pointer to buffer to be transmitted +// - `data_len` - how many bytes to transmit from `data` buffer. +// - `timeout` - maximum wait time to finish transmission. +// Returns: +// - `LORA_BUSY` in case of active transmission ongoing +// - `LORA_TIMEOUT` packet wasn't transmitted in given time frame. +// - `LORA_OK` packet scheduled to be sent. +uint8_t lora_send_packet_blocking(lora_sx1276 *lora, uint8_t *data, uint8_t data_len, uint32_t timeout); + + +// RECEIVE packet routines // + +// Checks if packet modem has packet awaiting to be received +// Returns 0 if no packet is available, or any positive integer in case packet is ready +uint8_t lora_is_packet_available(lora_sx1276 *lora); + +// If modem has packet awaiting to be received - returns it's length. +uint8_t lora_pending_packet_length(lora_sx1276 *lora); + +// Receives packet from LoRa modem +// Params: +// - `buffer` - pointer to buffer where copy packet to. +// - `buffer_len` - length of `buffer`. If incoming packet greater than `buffer_len` it will be truncated +// to fit `buffer_len`. +// - `error` - pointer to `uint8_t` to store error. Can be NULL - so no error information will be stored. +// Returns actual packet length stored into `buffer`. +// +// `error` is one of: +// - `LORA_OK` - packet successfully received. +// - `LORA_EMPTY` - no packet received at the moment (check for packet by `lora_is_packet_available()` before). +// - `LORA_TIMEOUT` - timeout while receiving packet (only for single receive mode). +// - `LORA_INVALID_HEADER` - packet with malformed header received. +// - `LORA_CRC_ERROR` - malformed packet received (CRC failed). Please note that you need to enable +// this functionality explicitly, it is disabled by default. +uint8_t lora_receive_packet(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error); + +// Start receiving packet from LoRa modem in DMA mode. +// 1. In case of single receive mode: when packet arrived or timeout occurred. +// Please note that it is not enough to set `timeout` to something positive - +// you also need to set timeout in LoRa modem by calling `lora_set_rx_symbol_timeout` before. +// 2. For continuous receiving mode will wait until packet arrived / timeout occurred. +// Params: +// - `buffer` - pointer to buffer where copy packet to. +// - `buffer_len` - length of `buffer`. If incoming packet greater than `buffer_len` it will be truncated +// to fit `buffer_len`. +// - `error` - pointer to `uint8_t` to store error. Can be NULL - so no error information will be stored. +// Returns actual packet length stored into `buffer`. +// +// `error` is one of: +// - `LORA_OK` - packet successfully received. +// - `LORA_EMPTY` - no packet received at the moment (check for packet by `lora_is_packet_available()` before). +// - `LORA_TIMEOUT` - timeout while receiving packet (only for single receive mode). +// - `LORA_INVALID_HEADER` - packet with malformed header received. +// - `LORA_CRC_ERROR` - malformed packet received (CRC failed). Please note that you need to enable +// this functionality explicitly, it is disabled by default. +uint8_t lora_receive_packet_dma_start(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, + uint8_t *error); + +// Finish receive packet in DMA dome +void lora_receive_packet_dma_complete(lora_sx1276 *lora); + + +// Receive packet in "blocking mode" i.e. function return only when packet: +// 1. In case of single receive mode: when packet arrived or timeout occurred. +// Please note that it is not enough to set `timeout` to something positive - +// you also need to set timeout in LoRa modem by calling `lora_set_rx_symbol_timeout` before. +// 2. For continuous receiving mode will wait until packet arrived / timeout occurred. +// Params: +// - `buffer` - pointer to buffer where copy packet to. +// - `buffer_len` - length of `buffer`. If incoming packet greater than `buffer_len` it will be truncated +// to fit `buffer_len`. +// - `error` - pointer to `uint8_t` to store error. Can be NULL - so no error information will be stored. +// Returns actual packet length stored into `buffer`. +// +// `error` is one of: +// - `LORA_OK` - packet successfully received. +// - `LORA_EMPTY` - no packet received at the moment (check for packet by `lora_is_packet_available()` before). +// - `LORA_TIMEOUT` - timeout while receiving packet (only for single receive mode). +// - `LORA_INVALID_HEADER` - packet with malformed header received. +// - `LORA_CRC_ERROR` - malformed packet received (CRC failed). Please note that you need to enable +// this functionality explicitly, it is disabled by default. +uint8_t lora_receive_packet_blocking(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, + uint32_t timeout, uint8_t *error); + +// Sets timeout for `lora_mode_receive_single()` in symbols. +// Params: +// - `symbols` - timeout value. Valid from `4` to `1024` symbols. +// For more information refer to datasheet section 4.1.5 +void lora_set_rx_symbol_timeout(lora_sx1276 *lora, uint16_t symbols); + + +// Enables interrupt on DIO0 when packet received +// SX1276 module will pull DIO0 line high +void lora_enable_interrupt_rx_done(lora_sx1276 *lora); + +// Enables interrupt on DIO0 when transmission is done +// SX1276 module will pull DIO0 line high +void lora_enable_interrupt_tx_done(lora_sx1276 *lora); + +// Clears all RX interrupts on DIO0 (done, timeout, crc, etc) +void lora_clear_interrupt_rx_all(lora_sx1276 *lora); + +// Clears TX interrupt on DIO0 +void lora_clear_interrupt_tx_done(lora_sx1276 *lora); + +#endif From 7812fad476ed3abf0000927ad37d5fae5f40c274 Mon Sep 17 00:00:00 2001 From: niekky Date: Tue, 12 Dec 2023 17:44:44 -0700 Subject: [PATCH 03/60] Added GD Firmware OP code --- commands/commands.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commands/commands.h b/commands/commands.h index b562616..57316bb 100644 --- a/commands/commands.h +++ b/commands/commands.h @@ -64,7 +64,8 @@ extern "C" { #define FIRMWARE_DATA_LOGGER ( 0x02 ) /* Data Logger Firmware */ #define FIRMWARE_DUAL_DEPLOY ( 0x03 ) /* Dual Deploy Firmware */ #define FIRMWARE_HOTFIRE ( 0x04 ) /* Hotfire Firmware */ - +#define FIRMWARE_GD_TRANSMITTER ( 0x05 ) /* Transmitter Firmware */ +#define FIRMWARE_GD_RECEIVER ( 0x06 ) /* Receiver Firmware */ /*------------------------------------------------------------------------------ Function Prototypes From 6142e47e74ad4633a371857bd4192da01a5b59e2 Mon Sep 17 00:00:00 2001 From: niekky Date: Tue, 12 Dec 2023 17:51:19 -0700 Subject: [PATCH 04/60] Added SEND_OP code --- commands/commands.h | 1 + 1 file changed, 1 insertion(+) diff --git a/commands/commands.h b/commands/commands.h index 57316bb..320caf9 100644 --- a/commands/commands.h +++ b/commands/commands.h @@ -31,6 +31,7 @@ extern "C" { #define SOL_OP 0x51 /* solenoid command opcode */ #define VALVE_OP 0x52 /* Valve command opcode */ #define DUAL_DEPLOY_OP 0xA0 /* dual-deploy command opcode */ +#define SEND_OP 0xB0 /* ground-station send opcode */ /* Board identifier code */ #if defined( A0002_REV1 ) /* Flight Computer Rev 1.0 */ From 62d4548d90b27d0a8a61352cb80c41c5984d14b0 Mon Sep 17 00:00:00 2001 From: niekky Date: Tue, 12 Dec 2023 18:07:13 -0700 Subject: [PATCH 05/60] Added Flight Ground Station Rev Ping Response Code --- commands/commands.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/commands/commands.h b/commands/commands.h index 320caf9..1dfafd1 100644 --- a/commands/commands.h +++ b/commands/commands.h @@ -58,8 +58,11 @@ extern "C" { #elif defined ( A0005_REV2 ) /* Ground Station Rev 2.0 */ /* Rev 2 */ #define PING_RESPONSE_CODE ( 0x09 ) +#elif defined ( A0005_REV1 ) /* Flight Ground Station Rev */ + #define PING_RESPONSE_CODE ( 0xA0 ) #endif + /* Firmware Identifier Code */ #define FIRMWARE_TERMINAL ( 0x01 ) /* Terminal Firmware */ #define FIRMWARE_DATA_LOGGER ( 0x02 ) /* Data Logger Firmware */ From 8bb96495571373c777cff65353fc982922585436 Mon Sep 17 00:00:00 2001 From: niekky Date: Sat, 1 Jun 2024 14:24:03 -0700 Subject: [PATCH 06/60] Deleted old library files --- LoRa/LoRa.c | 534 ---------------------------------------------------- LoRa/LoRa.h | 129 ------------- 2 files changed, 663 deletions(-) delete mode 100644 LoRa/LoRa.c delete mode 100644 LoRa/LoRa.h diff --git a/LoRa/LoRa.c b/LoRa/LoRa.c deleted file mode 100644 index 3d1f2bb..0000000 --- a/LoRa/LoRa.c +++ /dev/null @@ -1,534 +0,0 @@ -#include "LoRa.h" - -/* ----------------------------------------------------------------------------- *\ - name : newLoRa - - description : it's a constructor for LoRa structure that assign default values - and pass created object (LoRa struct instanse) - - arguments : Nothing - - returns : A LoRa object whith these default values: - ---------------------------------------- - | carrier frequency = 433 MHz | - | spreading factor = 7 | - | bandwidth = 125 KHz | - | coding rate = 4/5 | - ---------------------------------------- -\* ----------------------------------------------------------------------------- */ -LoRa newLoRa(){ - LoRa new_LoRa; - - new_LoRa.frequency = 433 ; - new_LoRa.spredingFactor = SF_7 ; - new_LoRa.bandWidth = BW_125KHz ; - new_LoRa.crcRate = CR_4_5 ; - new_LoRa.power = POWER_20db; - new_LoRa.overCurrentProtection = 100 ; - new_LoRa.preamble = 8 ; - - return new_LoRa; -} -/* ----------------------------------------------------------------------------- *\ - name : LoRa_reset - - description : reset module - - arguments : - LoRa* LoRa --> LoRa object handler - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_reset(LoRa* _LoRa){ - HAL_GPIO_WritePin(_LoRa->reset_port, _LoRa->reset_pin, GPIO_PIN_RESET); - HAL_Delay(1); - HAL_GPIO_WritePin(_LoRa->reset_port, _LoRa->reset_pin, GPIO_PIN_SET); - HAL_Delay(100); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_gotoMode - - description : set LoRa Op mode - - arguments : - LoRa* LoRa --> LoRa object handler - mode --> select from defined modes - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_gotoMode(LoRa* _LoRa, int mode){ - uint8_t read; - uint8_t data; - - read = LoRa_read(_LoRa, RegOpMode); - data = read; - - if(mode == SLEEP_MODE){ - data = (read & 0xF8) | 0x00; - _LoRa->current_mode = SLEEP_MODE; - }else if (mode == STNBY_MODE){ - data = (read & 0xF8) | 0x01; - _LoRa->current_mode = STNBY_MODE; - }else if (mode == TRANSMIT_MODE){ - data = (read & 0xF8) | 0x03; - _LoRa->current_mode = TRANSMIT_MODE; - }else if (mode == RXCONTIN_MODE){ - data = (read & 0xF8) | 0x05; - _LoRa->current_mode = RXCONTIN_MODE; - }else if (mode == RXSINGLE_MODE){ - data = (read & 0xF8) | 0x06; - _LoRa->current_mode = RXSINGLE_MODE; - } - - LoRa_write(_LoRa, RegOpMode, data); - //HAL_Delay(10); -} - - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_readReg - - description : read a register(s) by an address and a length, - then store value(s) at outpur array. - arguments : - LoRa* LoRa --> LoRa object handler - uint8_t* address --> pointer to the beginning of address array - uint16_t r_length --> detemines number of addresse bytes that - you want to send - uint8_t* output --> pointer to the beginning of output array - uint16_t w_length --> detemines number of bytes that you want to read - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_readReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* output, uint16_t w_length){ - HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_RESET); - HAL_SPI_Transmit(_LoRa->hSPIx, address, r_length, TRANSMIT_TIMEOUT); - while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) - ; - HAL_SPI_Receive(_LoRa->hSPIx, output, w_length, RECEIVE_TIMEOUT); - while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) - ; - HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_SET); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_writeReg - - description : write a value(s) in a register(s) by an address - - arguments : - LoRa* LoRa --> LoRa object handler - uint8_t* address --> pointer to the beginning of address array - uint16_t r_length --> detemines number of addresse bytes that - you want to send - uint8_t* output --> pointer to the beginning of values array - uint16_t w_length --> detemines number of bytes that you want to send - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_writeReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* values, uint16_t w_length){ - HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_RESET); - HAL_SPI_Transmit(_LoRa->hSPIx, address, r_length, TRANSMIT_TIMEOUT); - while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) - ; - HAL_SPI_Transmit(_LoRa->hSPIx, values, w_length, TRANSMIT_TIMEOUT); - while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) - ; - HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_SET); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_setFrequency - - description : set carrier frequency e.g 433 MHz - - arguments : - LoRa* LoRa --> LoRa object handler - int freq --> desired frequency in MHz unit, e.g 434 - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_setFrequency(LoRa* _LoRa, int freq){ - uint8_t data; - uint32_t F; - F = (freq * 524288)>>5; - - // write Msb: - data = F >> 16; - LoRa_write(_LoRa, RegFrMsb, data); - HAL_Delay(5); - - // write Mid: - data = F >> 8; - LoRa_write(_LoRa, RegFrMid, data); - HAL_Delay(5); - - // write Lsb: - data = F >> 0; - LoRa_write(_LoRa, RegFrLsb, data); - HAL_Delay(5); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_setSpreadingFactor - - description : set spreading factor, from 7 to 12. - - arguments : - LoRa* LoRa --> LoRa object handler - int SP --> desired spreading factor e.g 7 - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_setSpreadingFactor(LoRa* _LoRa, int SF){ - uint8_t data; - uint8_t read; - - if(SF>12) - SF = 12; - if(SF<7) - SF = 7; - - read = LoRa_read(_LoRa, RegModemConfig2); - HAL_Delay(10); - - data = (SF << 4) + (read & 0x0F); - LoRa_write(_LoRa, RegModemConfig2, data); - HAL_Delay(10); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_setPower - - description : set power gain. - - arguments : - LoRa* LoRa --> LoRa object handler - int power --> desired power like POWER_17db - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_setPower(LoRa* _LoRa, uint8_t power){ - LoRa_write(_LoRa, RegPaConfig, power); - HAL_Delay(10); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_setOCP - - description : set maximum allowed current. - - arguments : - LoRa* LoRa --> LoRa object handler - int current --> desired max currnet in mA, e.g 120 - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_setOCP(LoRa* _LoRa, uint8_t current){ - uint8_t OcpTrim = 0; - - if(current<45) - current = 45; - if(current>240) - current = 240; - - if(current <= 120) - OcpTrim = (current - 45)/5; - else if(current <= 240) - OcpTrim = (current + 30)/10; - - OcpTrim = OcpTrim + (1 << 5); - LoRa_write(_LoRa, RegOcp, OcpTrim); - HAL_Delay(10); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_setTOMsb_setCRCon - - description : set timeout msb to 0xFF + set CRC enable. - - arguments : - LoRa* LoRa --> LoRa object handler - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_setTOMsb_setCRCon(LoRa* _LoRa){ - uint8_t read, data; - - read = LoRa_read(_LoRa, RegModemConfig2); - - data = read | 0x07; - LoRa_write(_LoRa, RegModemConfig2, data);\ - HAL_Delay(10); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_read - - description : read a register by an address - - arguments : - LoRa* LoRa --> LoRa object handler - uint8_t address --> address of the register e.g 0x1D - - returns : register value -\* ----------------------------------------------------------------------------- */ -uint8_t LoRa_read(LoRa* _LoRa, uint8_t address){ - uint8_t read_data; - uint8_t data_addr; - - data_addr = address & 0x7F; - LoRa_readReg(_LoRa, &data_addr, 1, &read_data, 1); - //HAL_Delay(5); - - return read_data; -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_write - - description : write a value in a register by an address - - arguments : - LoRa* LoRa --> LoRa object handler - uint8_t address --> address of the register e.g 0x1D - uint8_t value --> value that you want to write - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_write(LoRa* _LoRa, uint8_t address, uint8_t value){ - uint8_t data; - uint8_t addr; - - addr = address | 0x80; - data = value; - LoRa_writeReg(_LoRa, &addr, 1, &data, 1); - //HAL_Delay(5); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_BurstWrite - - description : write a set of values in a register by an address respectively - - arguments : - LoRa* LoRa --> LoRa object handler - uint8_t address --> address of the register e.g 0x1D - uint8_t *value --> address of values that you want to write - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_BurstWrite(LoRa* _LoRa, uint8_t address, uint8_t *value, uint8_t length){ - uint8_t addr; - addr = address | 0x80; - - //NSS = 1 - HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_RESET); - - HAL_SPI_Transmit(_LoRa->hSPIx, &addr, 1, TRANSMIT_TIMEOUT); - while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) - ; - //Write data in FiFo - HAL_SPI_Transmit(_LoRa->hSPIx, value, length, TRANSMIT_TIMEOUT); - while (HAL_SPI_GetState(_LoRa->hSPIx) != HAL_SPI_STATE_READY) - ; - //NSS = 0 - //HAL_Delay(5); - HAL_GPIO_WritePin(_LoRa->CS_port, _LoRa->CS_pin, GPIO_PIN_SET); -} -/* ----------------------------------------------------------------------------- *\ - name : LoRa_isvalid - - description : check the LoRa instruct values - - arguments : - LoRa* LoRa --> LoRa object handler - - returns : returns 1 if all of the values were given, otherwise returns 0 -\* ----------------------------------------------------------------------------- */ -uint8_t LoRa_isvalid(LoRa* _LoRa){ - - return 1; -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_transmit - - description : Transmit data - - arguments : - LoRa* LoRa --> LoRa object handler - uint8_t data --> A pointer to the data you wanna send - uint8_t length --> Size of your data in Bytes - uint16_t timeOut --> Timeout in milliseconds - returns : 1 in case of success, 0 in case of timeout -\* ----------------------------------------------------------------------------- */ -uint8_t LoRa_transmit(LoRa* _LoRa, uint8_t* data, uint8_t length, uint16_t timeout){ - uint8_t read; - - int mode = _LoRa->current_mode; - LoRa_gotoMode(_LoRa, STNBY_MODE); - read = LoRa_read(_LoRa, RegFiFoTxBaseAddr); - LoRa_write(_LoRa, RegFiFoAddPtr, read); - LoRa_write(_LoRa, RegPayloadLength, length); - LoRa_BurstWrite(_LoRa, RegFiFo, data, length); - LoRa_gotoMode(_LoRa, TRANSMIT_MODE); - while(1){ - read = LoRa_read(_LoRa, RegIrqFlags); - if((read & 0x08)!=0){ - LoRa_write(_LoRa, RegIrqFlags, 0xFF); - LoRa_gotoMode(_LoRa, mode); - return 1; - } - else{ - if(--timeout==0){ - LoRa_gotoMode(_LoRa, mode); - return 0; - } - } - HAL_Delay(1); - } -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_startReceiving - - description : Start receiving continuously - - arguments : - LoRa* LoRa --> LoRa object handler - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -void LoRa_startReceiving(LoRa* _LoRa){ - LoRa_gotoMode(_LoRa, RXCONTIN_MODE); -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_Receive - - description : Read received data from module - - arguments : - LoRa* LoRa --> LoRa object handler - uint8_t data --> A pointer to the array that you want to write bytes in it - uint8_t length --> Determines how many bytes you want to read - - returns : The number of bytes received -\* ----------------------------------------------------------------------------- */ -uint8_t LoRa_receive(LoRa* _LoRa, uint8_t* data, uint8_t length){ - uint8_t read; - uint8_t number_of_bytes; - uint8_t min = 0; - - for(int i=0; i= number_of_bytes ? number_of_bytes : length; - for(int i=0; i LoRa object handler - - returns : Returns the RSSI value of last received packet. -\* ----------------------------------------------------------------------------- */ -int LoRa_getRSSI(LoRa* _LoRa){ - uint8_t read; - read = LoRa_read(_LoRa, RegPktRssiValue); - return -164 + read; -} - -/* ----------------------------------------------------------------------------- *\ - name : LoRa_init - - description : initialize and set the right setting according to LoRa sruct vars - - arguments : - LoRa* LoRa --> LoRa object handler - - returns : Nothing -\* ----------------------------------------------------------------------------- */ -uint16_t LoRa_init(LoRa* _LoRa){ - uint8_t data; - uint8_t read; - - if(LoRa_isvalid(_LoRa)){ - // goto sleep mode: - LoRa_gotoMode(_LoRa, SLEEP_MODE); - HAL_Delay(10); - - // turn on LoRa mode: - read = LoRa_read(_LoRa, RegOpMode); - HAL_Delay(10); - data = read | 0x80; - LoRa_write(_LoRa, RegOpMode, data); - HAL_Delay(100); - - // set frequency: - LoRa_setFrequency(_LoRa, _LoRa->frequency); - - // set output power gain: - LoRa_setPower(_LoRa, _LoRa->power); - - // set over current protection: - LoRa_setOCP(_LoRa, _LoRa->overCurrentProtection); - - // set LNA gain: - LoRa_write(_LoRa, RegLna, 0x23); - - // set spreading factor, CRC on, and Timeout Msb: - LoRa_setTOMsb_setCRCon(_LoRa); - LoRa_setSpreadingFactor(_LoRa, _LoRa->spredingFactor); - - // set Timeout Lsb: - LoRa_write(_LoRa, RegSymbTimeoutL, 0xFF); - - // set bandwidth, coding rate and expilicit mode: - // 8 bit RegModemConfig --> | X | X | X | X | X | X | X | X | - // bits represent --> | bandwidth | CR |I/E| - data = 0; - data = (_LoRa->bandWidth << 4) + (_LoRa->crcRate << 1); - LoRa_write(_LoRa, RegModemConfig1, data); - - // set preamble: - LoRa_write(_LoRa, RegPreambleMsb, _LoRa->preamble >> 8); - LoRa_write(_LoRa, RegPreambleLsb, _LoRa->preamble >> 0); - - // DIO mapping: --> DIO: RxDone - read = LoRa_read(_LoRa, RegDioMapping1); - data = read | 0x3F; - LoRa_write(_LoRa, RegDioMapping1, data); - - // goto standby mode: - LoRa_gotoMode(_LoRa, STNBY_MODE); - _LoRa->current_mode = STNBY_MODE; - HAL_Delay(10); - - read = LoRa_read(_LoRa, RegVersion); - if(read == 0x12) - return LORA_OK; - else - return LORA_NOT_FOUND; - } - else { - return LORA_UNAVAILABLE; - } -} \ No newline at end of file diff --git a/LoRa/LoRa.h b/LoRa/LoRa.h deleted file mode 100644 index 3d34af3..0000000 --- a/LoRa/LoRa.h +++ /dev/null @@ -1,129 +0,0 @@ -// -------------------------------------------------- \\ -// | | \\ -// | WRITTEN BY: Sslman Motlaq | \\ -// | Telegram: @S_Motlaq | \\ -// | E-MAIL: motlaq@aut.ac.ir | \\ -// | | \\ -// -------------------------------------------------- // - -#include "main.h" - -#define TRANSMIT_TIMEOUT 2000 -#define RECEIVE_TIMEOUT 2000 - -//--------- MODES ---------// -#define SLEEP_MODE 0 -#define STNBY_MODE 1 -#define TRANSMIT_MODE 3 -#define RXCONTIN_MODE 5 -#define RXSINGLE_MODE 6 - -//------- BANDWIDTH -------// -#define BW_7_8KHz 0 -#define BW_10_4KHz 1 -#define BW_15_6KHz 2 -#define BW_20_8KHz 3 -#define BW_31_25KHz 4 -#define BW_41_7KHz 5 -#define BW_62_5KHz 6 -#define BW_125KHz 7 -#define BW_250KHz 8 -#define BW_500KHz 9 - -//------ CODING RATE ------// -#define CR_4_5 1 -#define CR_4_6 2 -#define CR_4_7 3 -#define CR_4_8 4 - -//--- SPREADING FACTORS ---// -#define SF_7 7 -#define SF_8 8 -#define SF_9 9 -#define SF_10 10 -#define SF_11 11 -#define SF_12 12 - -//------ POWER GAIN ------// -#define POWER_11db 0xF6 -#define POWER_14db 0xF9 -#define POWER_17db 0xFC -#define POWER_20db 0xFF - -//------- REGISTERS -------// -#define RegFiFo 0x00 -#define RegOpMode 0x01 -#define RegFrMsb 0x06 -#define RegFrMid 0x07 -#define RegFrLsb 0x08 -#define RegPaConfig 0x09 -#define RegOcp 0x0B -#define RegLna 0x0C -#define RegFiFoAddPtr 0x0D -#define RegFiFoTxBaseAddr 0x0E -#define RegFiFoRxBaseAddr 0x0F -#define RegFiFoRxCurrentAddr 0x10 -#define RegIrqFlags 0x12 -#define RegRxNbBytes 0x13 -#define RegPktRssiValue 0x1A -#define RegModemConfig1 0x1D -#define RegModemConfig2 0x1E -#define RegSymbTimeoutL 0x1F -#define RegPreambleMsb 0x20 -#define RegPreambleLsb 0x21 -#define RegPayloadLength 0x22 -#define RegDioMapping1 0x40 -#define RegDioMapping2 0x41 -#define RegVersion 0x42 - -//------ LORA STATUS ------// -#define LORA_OK 200 -#define LORA_NOT_FOUND 404 -#define LORA_LARGE_PAYLOAD 413 -#define LORA_UNAVAILABLE 503 - -typedef struct LoRa_setting{ - - // Hardware setings: - GPIO_TypeDef* CS_port; - uint16_t CS_pin; - GPIO_TypeDef* reset_port; - uint16_t reset_pin; - GPIO_TypeDef* DIO0_port; - uint16_t DIO0_pin; - SPI_HandleTypeDef* hSPIx; - - // Module settings: - int current_mode; - int frequency; - uint8_t spredingFactor; - uint8_t bandWidth; - uint8_t crcRate; - uint16_t preamble; - uint8_t power; - uint8_t overCurrentProtection; - -} LoRa; - -LoRa newLoRa(void); -void LoRa_reset(LoRa* _LoRa); -void LoRa_readReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* output, uint16_t w_length); -void LoRa_writeReg(LoRa* _LoRa, uint8_t* address, uint16_t r_length, uint8_t* values, uint16_t w_length); -void LoRa_gotoMode(LoRa* _LoRa, int mode); -uint8_t LoRa_read(LoRa* _LoRa, uint8_t address); -void LoRa_write(LoRa* _LoRa, uint8_t address, uint8_t value); -void LoRa_BurstWrite(LoRa* _LoRa, uint8_t address, uint8_t *value, uint8_t length); -uint8_t LoRa_isvalid(LoRa* _LoRa); - -void LoRa_setFrequency(LoRa* _LoRa, int freq); -void LoRa_setSpreadingFactor(LoRa* _LoRa, int SP); -void LoRa_setPower(LoRa* _LoRa, uint8_t power); -void LoRa_setOCP(LoRa* _LoRa, uint8_t current); -void LoRa_setTOMsb_setCRCon(LoRa* _LoRa); -uint8_t LoRa_transmit(LoRa* _LoRa, uint8_t* data, uint8_t length, uint16_t timeout); -void LoRa_startReceiving(LoRa* _LoRa); -uint8_t LoRa_receive(LoRa* _LoRa, uint8_t* data, uint8_t length); -void LoRa_receive_IT(LoRa* _LoRa, uint8_t* data, uint8_t length); -int LoRa_getRSSI(LoRa* _LoRa); - -uint16_t LoRa_init(LoRa* _LoRa); \ No newline at end of file From 33ecf19abea290f75272a52a6d4388369a7d2a24 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 13 Sep 2024 18:34:26 -0700 Subject: [PATCH 07/60] Define register addresses for LoRa module --- LoRa/LoRa.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 LoRa/LoRa.h diff --git a/LoRa/LoRa.h b/LoRa/LoRa.h new file mode 100644 index 0000000..5c6dda8 --- /dev/null +++ b/LoRa/LoRa.h @@ -0,0 +1,64 @@ +/******************************************************************************* +* +* FILE: +* LoRa.h +* +* DESCRIPTION: +* Contains register definitions and functions for controlling the LoRa +* radio module. +* +*******************************************************************************/ + +/* Standard includes */ +#include + +/* Project includes */ +#include "sensor.h" + +/* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) + Note: as we are using LoRa, the FSK opcodes are not included*/ +#define LORA_REG_FIFO_RW 0x00 +#define LORA_REG_OPERATION_MODE 0x01 +#define LORA_REG_FREQ_MSB 0x06 +#define LORA_REG_FREQ_MSD 0x07 +#define LORA_REG_FREQ_LSB 0x08 +#define LORA_REG_PA_CONFIG 0x09 +#define LORA_REG_PA_RAMP 0x0A +#define LORA_REG_OVER_CURRENT_PROT_CTRL 0x0B +#define LORA_REG_LNA_SETTINGS 0x0C +#define LORA_REG_FIFO_SPI_POINTER 0x0D +#define LORA_REG_FIFO_TX_DATA 0x0E +#define LORA_REG_FIFO_RX_DATA 0x0F +#define LORA_REG_LORA_STATE_FLAGS 0x10 +#define LORA_REG_LORA_FLAG_MASK 0x11 +#define LORA_REG_INTERMEDIATE_FREQ_MSB 0x12 +#define LORA_REG_INTERMEDIATE_FREQ_LSB 0x13 +#define LORA_REG_RCV_TIMEOUT_MSB 0x14 +#define LORA_REG_RCV_TIMEOUT_LSB 0x15 +#define LORA_REG_TRANS_CONFIG 0x16 +#define LORA_REG_TRANS_PAYLOAD_LENGTH 0x17 +#define LORA_REG_PREAMBLE_SIZE_MSB 0x18 +#define LORA_REG_PREAMBLE_SIZE_LSB 0x19 +#define LORA_REG_MODULATION_CONFIG 0x1A +#define LORA_REG_RF_MODE 0x1B +#define LORA_REG_FHSS_HOP_PERIOD 0x1C +#define LORA_REG_NUM_RX_BYTES 0x1D +#define LORA_REG_RX_HEADER_INFO 0x1E +#define LORA_REG_NUM_RX_VALID_HEADERS 0x1F +#define LORA_REG_NUM_RX_VALID_PACKETS 0x20 +#define LORA_REG_MODEM_STATUS 0x21 +#define LORA_REG_SIGNAL_TO_NOISE 0x22 +#define LORA_REG_CURRENT_RSSI 0x23 +#define LORA_REG_LAST_PACKET_RSSI 0x24 +#define LORA_REG_FREQ_HOP_START_CHANNEL 0x25 +#define LORA_REG_RX_DATA_POINTER 0x26 +#define LORA_REG_DIO_MAPPING_MODE_1 0x40 +#define LORA_REG_DIO_MAPPING_MODE_2 0x41 +#define LORA_REG_ID_VERSION 0x42 +#define LORA_REG_TCXO_OR_XTAL 0x4B +#define LORA_REG_PA_SETTINGS 0x4D +#define LORA_REG_FORMER_TEMP 0x5B +#define LORA_REG_AGC_REFERENCE 0x61 +#define LORA_REG_AGC_THRESHOLD_1 0x62 +#define LORA_REG_AGC_THRESHOLD_2 0x63 +#define LORA_REG_AGC_THRESHOLD_4 0x64 \ No newline at end of file From a7ab7c55e2fb50cbd0e176ffcca8e642e40ff45d Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 13 Sep 2024 19:19:06 -0700 Subject: [PATCH 08/60] Make LoRa folder naming convention comply with other --- LoRa/LoRa.h => lora/lora.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LoRa/LoRa.h => lora/lora.h (100%) diff --git a/LoRa/LoRa.h b/lora/lora.h similarity index 100% rename from LoRa/LoRa.h rename to lora/lora.h From 264a9209b6fec5bd2dfbe52612dc0b8f32e73eb5 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 20 Sep 2024 16:22:16 -0700 Subject: [PATCH 09/60] Add register values for modes and basic lora.c imports --- lora/lora.c | 26 ++++++++++++++++++++++++++ lora/lora.h | 22 +++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 lora/lora.c diff --git a/lora/lora.c b/lora/lora.c new file mode 100644 index 0000000..a387603 --- /dev/null +++ b/lora/lora.c @@ -0,0 +1,26 @@ +/******************************************************************************* +* +* FILE: +* lora.c +* +* DESCRIPTION: +* Contains API functions for transmating and receiving from the board's +* built-in LoRa module. +* +*******************************************************************************/ + +#include "stm32h7xx_hal.h" +/*------------------------------------------------------------------------------ + Standard Includes +------------------------------------------------------------------------------*/ +#include + + +/*------------------------------------------------------------------------------ + MCU Pins +------------------------------------------------------------------------------*/ +#if defined( FLIGHT_COMPUTER ) + #include "sdr_pin_defines_A0002.h" +#elif defined( GROUND_STATION ) + #include "sdr_pin_defines_A0005.h" +#endif \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index 5c6dda8..13a7570 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -9,12 +9,30 @@ * *******************************************************************************/ +#ifndef LORA_H +#define LORA_H + /* Standard includes */ #include /* Project includes */ #include "sensor.h" +/* Operation Mode Register Values */ +#define LORA_LORA_MODE 0b1 +#define LORA_LORA_REGISTER_PAGE 0b0 +#define LORA_FSK_REGISTER_PAGE 0b1 +#define LORA_HIGH_FREQ_MODE 0b1 +#define LORA_LOW_FREQ_MODE 0b0 +#define LORA_OPERATION_RESERVED 0b00 +#define LORA_SLEEP_MODE 0b000 +#define LORA_STANDBY_MODE 0b001 +#define LORA_FREQ_SYNTH_TX_MODE 0b010 +#define LORA_TRANSMIT_MODE 0b011 +#define LORA_FREQ_SYNTH_RX_MODE 0b100 +#define LORA_RX_CONTINUOUS_MODE 0b101 +#define LORA_RX_SINGLE_MODE 0b111 + /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) Note: as we are using LoRa, the FSK opcodes are not included*/ #define LORA_REG_FIFO_RW 0x00 @@ -61,4 +79,6 @@ #define LORA_REG_AGC_REFERENCE 0x61 #define LORA_REG_AGC_THRESHOLD_1 0x62 #define LORA_REG_AGC_THRESHOLD_2 0x63 -#define LORA_REG_AGC_THRESHOLD_4 0x64 \ No newline at end of file +#define LORA_REG_AGC_THRESHOLD_4 0x64 + +#endif \ No newline at end of file From bc806de2dfe58788fa438de10fe551fa0065091b Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 20 Sep 2024 17:20:37 -0700 Subject: [PATCH 10/60] Add function to set chip mode --- lora/lora.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lora/lora.c b/lora/lora.c index a387603..a594674 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -23,4 +23,31 @@ #include "sdr_pin_defines_A0002.h" #elif defined( GROUND_STATION ) #include "sdr_pin_defines_A0005.h" -#endif \ No newline at end of file +#endif + +/*------------------------------------------------------------------------------ + Function to set the mode of the chip +------------------------------------------------------------------------------*/ + +void set_chip_mode( uint8_t chip_mode ) { + // I may give this function a return type in the future to check success of operation. + // Also, may need to be updated based on pin definitions after those are fixed. + + // Pull chip select low + HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, LOSS_SS_GPIO_PIN, GPIO_PIN_RESET ); + + // Get initial value of the operation mode register + HAL_StatusTypeDef operation_mode_register = HAL_SPI_Receive( &(LORA_SPI), &(LORA_REG_OPERATION_MODE), 1, HAL_DEFAULT_TIMEOUT ); + + // Shift the chip mode bits to be the first 3 bits of the sequence + uint8_t shifted_chip_mode = (chip_mode << 0b00000); + + // Change the value of the chip register to set it to the suggested chip mode + uint8_t new_opmode_register = (operation_mode_register | chip_mode); + + // Write new bit + HAL_SPI_Transmit( &(LORA_SPI), &new_opmode_register, 1, HAL_DEFAULT_TIMEOUT); + + // Bring chip select back high + HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, LOSS_SS_GPIO_PIN, GPIO_PIN_SET ); +} \ No newline at end of file From 558d0ee171eaa2ef2ec425f28f1137409999b3db Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 20 Sep 2024 17:23:29 -0700 Subject: [PATCH 11/60] Add a little bit of documentation in the function --- lora/lora.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lora/lora.c b/lora/lora.c index a594674..c4226e8 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -30,6 +30,15 @@ ------------------------------------------------------------------------------*/ void set_chip_mode( uint8_t chip_mode ) { + /* chip_mode should be one of the following 3-bit variables defined in lora.h + #define LORA_SLEEP_MODE 0b000 + #define LORA_STANDBY_MODE 0b001 + #define LORA_FREQ_SYNTH_TX_MODE 0b010 + #define LORA_TRANSMIT_MODE 0b011 + #define LORA_FREQ_SYNTH_RX_MODE 0b100 + #define LORA_RX_CONTINUOUS_MODE 0b101 + #define LORA_RX_SINGLE_MODE 0b111 + */ // I may give this function a return type in the future to check success of operation. // Also, may need to be updated based on pin definitions after those are fixed. From ea5cf9ff829f36b32536ca9f09fe8a974f963d3c Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Sat, 21 Sep 2024 12:42:58 -0700 Subject: [PATCH 12/60] Create helper functions and port set_lora_chip_mode to them --- lora/lora.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index c4226e8..d677ab6 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -25,11 +25,32 @@ #include "sdr_pin_defines_A0005.h" #endif +/*------------------------------------------------------------------------------ + Helper functions for various pin functions on the LoRa modem. +------------------------------------------------------------------------------*/ +void lora_write_cs_pin( GPIO_PinState pinState ) { + /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin + high or low.*/ + HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, pinState ); +} + +HAL_StatusTypeDef lora_spi_receive( uint8_t *register ) { + /* Takes pointer to the requested register. The response size is set to + 1 byte, as that is the size of the LoRa module's registers*/ + return HAL_SPI_Receive( &(LORA_SPI), &(register)), 1, HAL_DEFAULT_TIMEOUT ); +} + +HAL_StatusTypeDef lora_spi_transmit( uint8_t register, uint8_t data ) { + /* Takes register and data to write (1 byte) and writes that register. */ + uint8_t transmitBuffer[2] = { register, data }; + HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 2, HAL_DEFAULT_TIMEOUT); +} + /*------------------------------------------------------------------------------ Function to set the mode of the chip ------------------------------------------------------------------------------*/ -void set_chip_mode( uint8_t chip_mode ) { +void set_lora_chip_mode( uint8_t chip_mode ) { /* chip_mode should be one of the following 3-bit variables defined in lora.h #define LORA_SLEEP_MODE 0b000 #define LORA_STANDBY_MODE 0b001 @@ -43,10 +64,10 @@ void set_chip_mode( uint8_t chip_mode ) { // Also, may need to be updated based on pin definitions after those are fixed. // Pull chip select low - HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, LOSS_SS_GPIO_PIN, GPIO_PIN_RESET ); + lora_write_cs_pin( GPIO_PIN_RESET ); // Get initial value of the operation mode register - HAL_StatusTypeDef operation_mode_register = HAL_SPI_Receive( &(LORA_SPI), &(LORA_REG_OPERATION_MODE), 1, HAL_DEFAULT_TIMEOUT ); + HAL_StatusTypeDef operation_mode_register = lora_spi_receive( &(LORA_REG_OPERATION_MODE) ); // Shift the chip mode bits to be the first 3 bits of the sequence uint8_t shifted_chip_mode = (chip_mode << 0b00000); @@ -55,8 +76,8 @@ void set_chip_mode( uint8_t chip_mode ) { uint8_t new_opmode_register = (operation_mode_register | chip_mode); // Write new bit - HAL_SPI_Transmit( &(LORA_SPI), &new_opmode_register, 1, HAL_DEFAULT_TIMEOUT); + lora_spi_transmit( LORA_REG_OPERATION_MODE, new_opmode_register ); // Bring chip select back high - HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, LOSS_SS_GPIO_PIN, GPIO_PIN_SET ); + lora_write_cs_pin( GPIO_PIN_RESET ); } \ No newline at end of file From c8edb9114b2c8e6bcc73d33ff877ab5cb0d5bf7c Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 27 Sep 2024 18:04:42 -0700 Subject: [PATCH 13/60] Create new Enums and get rid of HAL types --- lora/lora.c | 14 +++++-- lora/lora.h | 117 ++++++++++++++++++++++++++++------------------------ 2 files changed, 72 insertions(+), 59 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index d677ab6..6b7448d 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -25,22 +25,28 @@ #include "sdr_pin_defines_A0005.h" #endif +/*------------------------------------------------------------------------------ + Project Inlcudes +------------------------------------------------------------------------------*/ +#include lora.h + /*------------------------------------------------------------------------------ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ -void lora_write_cs_pin( GPIO_PinState pinState ) { +void lora_write_cs_pin( bool pinState ) { /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin high or low.*/ HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, pinState ); } -HAL_StatusTypeDef lora_spi_receive( uint8_t *register ) { +uint8_t lora_spi_receive( LORA_REGISTER_ADDR *register ) { /* Takes pointer to the requested register. The response size is set to 1 byte, as that is the size of the LoRa module's registers*/ return HAL_SPI_Receive( &(LORA_SPI), &(register)), 1, HAL_DEFAULT_TIMEOUT ); } -HAL_StatusTypeDef lora_spi_transmit( uint8_t register, uint8_t data ) { +void lora_spi_transmit( LORA_REGISTER_ADDR *register, uint8_t data ) { + // TODO: Actually make this return something /* Takes register and data to write (1 byte) and writes that register. */ uint8_t transmitBuffer[2] = { register, data }; HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 2, HAL_DEFAULT_TIMEOUT); @@ -50,7 +56,7 @@ HAL_StatusTypeDef lora_spi_transmit( uint8_t register, uint8_t data ) { Function to set the mode of the chip ------------------------------------------------------------------------------*/ -void set_lora_chip_mode( uint8_t chip_mode ) { +void set_lora_chip_mode( LORA_CHIPMODE chip_mode ) { /* chip_mode should be one of the following 3-bit variables defined in lora.h #define LORA_SLEEP_MODE 0b000 #define LORA_STANDBY_MODE 0b001 diff --git a/lora/lora.h b/lora/lora.h index 13a7570..a690192 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -12,73 +12,80 @@ #ifndef LORA_H #define LORA_H -/* Standard includes */ -#include - /* Project includes */ #include "sensor.h" /* Operation Mode Register Values */ +/* These are just random parts of the operation register that may or not get used +To avoid any chance they're in the final binary without being used, +they are commented out for now and will be uncommented as they're needed. + #define LORA_LORA_MODE 0b1 #define LORA_LORA_REGISTER_PAGE 0b0 #define LORA_FSK_REGISTER_PAGE 0b1 #define LORA_HIGH_FREQ_MODE 0b1 #define LORA_LOW_FREQ_MODE 0b0 #define LORA_OPERATION_RESERVED 0b00 -#define LORA_SLEEP_MODE 0b000 -#define LORA_STANDBY_MODE 0b001 -#define LORA_FREQ_SYNTH_TX_MODE 0b010 -#define LORA_TRANSMIT_MODE 0b011 -#define LORA_FREQ_SYNTH_RX_MODE 0b100 -#define LORA_RX_CONTINUOUS_MODE 0b101 -#define LORA_RX_SINGLE_MODE 0b111 +*/ + +typedef enum LORA_CHIPMODE { + LORA_SLEEP_MODE = 0b000, + LORA_STANDBY_MODE = 0b001, + LORA_FREQ_SYNTH_TX_MODE = 0b010, + LORA_TRANSMIT_MODE = 0b011, + LORA_FREQ_SYNTH_RX_MODE = 0b100, + LORA_RX_CONTINUOUS_MODE = 0b101, + LORA_RX_SINGLE_MODE = 0b111, +} LORA_CHIPMODE; /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) Note: as we are using LoRa, the FSK opcodes are not included*/ -#define LORA_REG_FIFO_RW 0x00 -#define LORA_REG_OPERATION_MODE 0x01 -#define LORA_REG_FREQ_MSB 0x06 -#define LORA_REG_FREQ_MSD 0x07 -#define LORA_REG_FREQ_LSB 0x08 -#define LORA_REG_PA_CONFIG 0x09 -#define LORA_REG_PA_RAMP 0x0A -#define LORA_REG_OVER_CURRENT_PROT_CTRL 0x0B -#define LORA_REG_LNA_SETTINGS 0x0C -#define LORA_REG_FIFO_SPI_POINTER 0x0D -#define LORA_REG_FIFO_TX_DATA 0x0E -#define LORA_REG_FIFO_RX_DATA 0x0F -#define LORA_REG_LORA_STATE_FLAGS 0x10 -#define LORA_REG_LORA_FLAG_MASK 0x11 -#define LORA_REG_INTERMEDIATE_FREQ_MSB 0x12 -#define LORA_REG_INTERMEDIATE_FREQ_LSB 0x13 -#define LORA_REG_RCV_TIMEOUT_MSB 0x14 -#define LORA_REG_RCV_TIMEOUT_LSB 0x15 -#define LORA_REG_TRANS_CONFIG 0x16 -#define LORA_REG_TRANS_PAYLOAD_LENGTH 0x17 -#define LORA_REG_PREAMBLE_SIZE_MSB 0x18 -#define LORA_REG_PREAMBLE_SIZE_LSB 0x19 -#define LORA_REG_MODULATION_CONFIG 0x1A -#define LORA_REG_RF_MODE 0x1B -#define LORA_REG_FHSS_HOP_PERIOD 0x1C -#define LORA_REG_NUM_RX_BYTES 0x1D -#define LORA_REG_RX_HEADER_INFO 0x1E -#define LORA_REG_NUM_RX_VALID_HEADERS 0x1F -#define LORA_REG_NUM_RX_VALID_PACKETS 0x20 -#define LORA_REG_MODEM_STATUS 0x21 -#define LORA_REG_SIGNAL_TO_NOISE 0x22 -#define LORA_REG_CURRENT_RSSI 0x23 -#define LORA_REG_LAST_PACKET_RSSI 0x24 -#define LORA_REG_FREQ_HOP_START_CHANNEL 0x25 -#define LORA_REG_RX_DATA_POINTER 0x26 -#define LORA_REG_DIO_MAPPING_MODE_1 0x40 -#define LORA_REG_DIO_MAPPING_MODE_2 0x41 -#define LORA_REG_ID_VERSION 0x42 -#define LORA_REG_TCXO_OR_XTAL 0x4B -#define LORA_REG_PA_SETTINGS 0x4D -#define LORA_REG_FORMER_TEMP 0x5B -#define LORA_REG_AGC_REFERENCE 0x61 -#define LORA_REG_AGC_THRESHOLD_1 0x62 -#define LORA_REG_AGC_THRESHOLD_2 0x63 -#define LORA_REG_AGC_THRESHOLD_4 0x64 +typedef enum LORA_REGISTER_ADDR { + LORA_REG__FIFO_RW = 0x00, + LORA_REG__OPERATION_MODE = 0x01, + LORA_REG__FREQ_MSB = 0x06, + LORA_REG__FREQ_MSD = 0x07, + LORA_REG__FREQ_LSB = 0x08, + LORA_REG__PA_CONFIG = 0x09, + LORA_REG__PA_RAMP = 0x0A, + LORA_REG__OVER_CURRENT_PROT_CTRL = 0x0B, + LORA_REG__LNA_SETTINGS = 0x0C, + LORA_REG__FIFO_SPI_POINTER = 0x0D, + LORA_REG__FIFO_TX_DATA = 0x0E, + LORA_REG__FIFO_RX_DATA = 0x0F, + LORA_REG__LORA_STATE_FLAGS = 0x10, + LORA_REG__LORA_FLAG_MASK = 0x11, + LORA_REG__INTERMEDIATE_FREQ_MSB = 0x12, + LORA_REG__INTERMEDIATE_FREQ_LSB = 0x13, + LORA_REG__RCV_TIMEOUT_MSB = 0x14, + LORA_REG__RCV_TIMEOUT_LSB = 0x15, + LORA_REG__TRANS_CONFIG = 0x16, + LORA_REG__TRANS_PAYLOAD_LENGTH = 0x17, + LORA_REG__PREAMBLE_SIZE_MSB = 0x18, + LORA_REG__PREAMBLE_SIZE_LSB = 0x19, + LORA_REG__MODULATION_CONFIG = 0x1A, + LORA_REG__RF_MODE = 0x1B, + LORA_REG__FHSS_HOP_PERIOD = 0x1C, + LORA_REG__NUM_RX_BYTES = 0x1D, + LORA_REG__RX_HEADER_INFO = 0x1E, + LORA_REG__NUM_RX_VALID_HEADERS = 0x1F, + LORA_REG__NUM_RX_VALID_PACKETS = 0x20, + LORA_REG__MODEM_STATUS = 0x21, + LORA_REG__SIGNAL_TO_NOISE = 0x22, + LORA_REG__CURRENT_RSSI = 0x23, + LORA_REG__LAST_PACKET_RSSI = 0x24, + LORA_REG__FREQ_HOP_START_CHANNEL = 0x25, + LORA_REG__RX_DATA_POINTER = 0x26, + LORA_REG__DIO_MAPPING_MODE_1 = 0x40, + LORA_REG__DIO_MAPPING_MODE_2 = 0x41, + LORA_REG__ID_VERSION = 0x42, + LORA_REG__TCXO_OR_XTAL = 0x4B, + LORA_REG__PA_SETTINGS = 0x4D, + LORA_REG__FORMER_TEMP = 0x5B, + LORA_REG__AGC_REFERENCE = 0x61, + LORA_REG__AGC_THRESHOLD_1 = 0x62, + LORA_REG__AGC_THRESHOLD_2 = 0x63, + LORA_REG__AGC_THRESHOLD_4 = 0x64 +} LORA_REGISTER_ADDR; #endif \ No newline at end of file From 38282e7516fa36cc55b0690278f9473b88c22040 Mon Sep 17 00:00:00 2001 From: niekky Date: Sat, 28 Sep 2024 14:46:58 -0700 Subject: [PATCH 14/60] correct way to do cs --- lora/lora.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lora/lora.c b/lora/lora.c index 6b7448d..94b7e31 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -37,6 +37,9 @@ void lora_write_cs_pin( bool pinState ) { /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin high or low.*/ HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, pinState ); + // HAL_GPIO_WritePin(LORA_NSS_PORT, LORA_NSS_PIN, GPIO_PIN_SET); + + } uint8_t lora_spi_receive( LORA_REGISTER_ADDR *register ) { From b034e06acde175df3e3d56fcd37cb1c27c8251e1 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Tue, 1 Oct 2024 16:39:24 -0700 Subject: [PATCH 15/60] Update SPI calls to behave more like how the protocol actually works --- lora/lora.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 94b7e31..6fb97dc 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -33,26 +33,37 @@ /*------------------------------------------------------------------------------ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ +//TODO: Switch pinState to a good enum void lora_write_cs_pin( bool pinState ) { /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin high or low.*/ - HAL_GPIO_WritePin( LORA_SS_GPIO_PORT, pinState ); - // HAL_GPIO_WritePin(LORA_NSS_PORT, LORA_NSS_PIN, GPIO_PIN_SET); - - + HAL_GPIO_WritePin( LORA_NSS_PORT, pinState ); } -uint8_t lora_spi_receive( LORA_REGISTER_ADDR *register ) { - /* Takes pointer to the requested register. The response size is set to - 1 byte, as that is the size of the LoRa module's registers*/ - return HAL_SPI_Receive( &(LORA_SPI), &(register)), 1, HAL_DEFAULT_TIMEOUT ); +void lora_spi_receive( uint8_t *read_buffer[2] ) { + /* Takes pointer to the read buffer. and puts output there */ + read_buffer = HAL_SPI_Receive( &(hspi4), &(read_buffer), 2, HAL_DEFAULT_TIMEOUT ); } -void lora_spi_transmit( LORA_REGISTER_ADDR *register, uint8_t data ) { +void lora_spi_transmit( LORA_REGISTER_ADDR register, uint8_t data ) { // TODO: Actually make this return something /* Takes register and data to write (1 byte) and writes that register. */ uint8_t transmitBuffer[2] = { register, data }; - HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 2, HAL_DEFAULT_TIMEOUT); + HAL_SPI_Transmit( &(hspi4), &transmitBuffer, 2, HAL_DEFAULT_TIMEOUT); +} + +uint8_t lora_spi_get_register( LORA_REGISTER_ADDR lora_register ) { + uint8_t read_buffer[2]; + + lora_spi_transmit( (lora_register | 0b00000000), 0b00000000 ); + + lora_spi_receive( &read_buffer ); + + return read_buffer[2]; +} + +void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { + lora_spi_transmit( (lora_register | 0b10000000), data ); } /*------------------------------------------------------------------------------ @@ -73,10 +84,10 @@ void set_lora_chip_mode( LORA_CHIPMODE chip_mode ) { // Also, may need to be updated based on pin definitions after those are fixed. // Pull chip select low - lora_write_cs_pin( GPIO_PIN_RESET ); + lora_write_cs_pin( GPIO_PIN_SET ); // Get initial value of the operation mode register - HAL_StatusTypeDef operation_mode_register = lora_spi_receive( &(LORA_REG_OPERATION_MODE) ); + uint8_t operation_mode_register = lora_spi_get_register( &(LORA_REG_OPERATION_MODE) ); // Shift the chip mode bits to be the first 3 bits of the sequence uint8_t shifted_chip_mode = (chip_mode << 0b00000); @@ -85,7 +96,7 @@ void set_lora_chip_mode( LORA_CHIPMODE chip_mode ) { uint8_t new_opmode_register = (operation_mode_register | chip_mode); // Write new bit - lora_spi_transmit( LORA_REG_OPERATION_MODE, new_opmode_register ); + lora_spi_set_register( LORA_REG_OPERATION_MODE, new_opmode_register ); // Bring chip select back high lora_write_cs_pin( GPIO_PIN_RESET ); From 6a44f007cb1828bca3dd4592d9c13e7d82926012 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Tue, 1 Oct 2024 18:15:33 -0700 Subject: [PATCH 16/60] Add get device id function --- lora/lora.c | 14 ++++++--- lora/lora.h | 90 ++++++++++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 6fb97dc..81dfd14 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -34,7 +34,7 @@ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ //TODO: Switch pinState to a good enum -void lora_write_cs_pin( bool pinState ) { +void lora_write_cs_pin( bool pinState ) {LORA_SPI /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin high or low.*/ HAL_GPIO_WritePin( LORA_NSS_PORT, pinState ); @@ -70,7 +70,7 @@ void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { Function to set the mode of the chip ------------------------------------------------------------------------------*/ -void set_lora_chip_mode( LORA_CHIPMODE chip_mode ) { +void lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { /* chip_mode should be one of the following 3-bit variables defined in lora.h #define LORA_SLEEP_MODE 0b000 #define LORA_STANDBY_MODE 0b001 @@ -87,7 +87,7 @@ void set_lora_chip_mode( LORA_CHIPMODE chip_mode ) { lora_write_cs_pin( GPIO_PIN_SET ); // Get initial value of the operation mode register - uint8_t operation_mode_register = lora_spi_get_register( &(LORA_REG_OPERATION_MODE) ); + uint8_t operation_mode_register = lora_spi_get_register( LORA_REG_OPERATION_MODE ); // Shift the chip mode bits to be the first 3 bits of the sequence uint8_t shifted_chip_mode = (chip_mode << 0b00000); @@ -96,8 +96,14 @@ void set_lora_chip_mode( LORA_CHIPMODE chip_mode ) { uint8_t new_opmode_register = (operation_mode_register | chip_mode); // Write new bit - lora_spi_set_register( LORA_REG_OPERATION_MODE, new_opmode_register ); + lora_spi_set_register( LORA_REG_OPERATION_MODE, new_opmode_register );LORA_REG_ // Bring chip select back high lora_write_cs_pin( GPIO_PIN_RESET ); +} + +// Get the device chip ID +uint8_t lora_get_device_id() { + uint8_t[2] chip_id_packet = lora_spi_get_register( LORA_REG_ID_VERSION ); + return chip_id_packet[1]; } \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index a690192..42dd864 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -41,51 +41,51 @@ typedef enum LORA_CHIPMODE { /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) Note: as we are using LoRa, the FSK opcodes are not included*/ typedef enum LORA_REGISTER_ADDR { - LORA_REG__FIFO_RW = 0x00, - LORA_REG__OPERATION_MODE = 0x01, - LORA_REG__FREQ_MSB = 0x06, - LORA_REG__FREQ_MSD = 0x07, - LORA_REG__FREQ_LSB = 0x08, - LORA_REG__PA_CONFIG = 0x09, - LORA_REG__PA_RAMP = 0x0A, - LORA_REG__OVER_CURRENT_PROT_CTRL = 0x0B, - LORA_REG__LNA_SETTINGS = 0x0C, - LORA_REG__FIFO_SPI_POINTER = 0x0D, - LORA_REG__FIFO_TX_DATA = 0x0E, - LORA_REG__FIFO_RX_DATA = 0x0F, - LORA_REG__LORA_STATE_FLAGS = 0x10, - LORA_REG__LORA_FLAG_MASK = 0x11, - LORA_REG__INTERMEDIATE_FREQ_MSB = 0x12, - LORA_REG__INTERMEDIATE_FREQ_LSB = 0x13, - LORA_REG__RCV_TIMEOUT_MSB = 0x14, - LORA_REG__RCV_TIMEOUT_LSB = 0x15, - LORA_REG__TRANS_CONFIG = 0x16, - LORA_REG__TRANS_PAYLOAD_LENGTH = 0x17, - LORA_REG__PREAMBLE_SIZE_MSB = 0x18, - LORA_REG__PREAMBLE_SIZE_LSB = 0x19, - LORA_REG__MODULATION_CONFIG = 0x1A, - LORA_REG__RF_MODE = 0x1B, - LORA_REG__FHSS_HOP_PERIOD = 0x1C, - LORA_REG__NUM_RX_BYTES = 0x1D, - LORA_REG__RX_HEADER_INFO = 0x1E, - LORA_REG__NUM_RX_VALID_HEADERS = 0x1F, - LORA_REG__NUM_RX_VALID_PACKETS = 0x20, - LORA_REG__MODEM_STATUS = 0x21, - LORA_REG__SIGNAL_TO_NOISE = 0x22, - LORA_REG__CURRENT_RSSI = 0x23, - LORA_REG__LAST_PACKET_RSSI = 0x24, - LORA_REG__FREQ_HOP_START_CHANNEL = 0x25, - LORA_REG__RX_DATA_POINTER = 0x26, - LORA_REG__DIO_MAPPING_MODE_1 = 0x40, - LORA_REG__DIO_MAPPING_MODE_2 = 0x41, - LORA_REG__ID_VERSION = 0x42, - LORA_REG__TCXO_OR_XTAL = 0x4B, - LORA_REG__PA_SETTINGS = 0x4D, - LORA_REG__FORMER_TEMP = 0x5B, - LORA_REG__AGC_REFERENCE = 0x61, - LORA_REG__AGC_THRESHOLD_1 = 0x62, - LORA_REG__AGC_THRESHOLD_2 = 0x63, - LORA_REG__AGC_THRESHOLD_4 = 0x64 + LORA_REG_FIFO_RW = 0x00, + LORA_REG_OPERATION_MODE = 0x01, + LORA_REG_FREQ_MSB = 0x06, + LORA_REG_FREQ_MSD = 0x07, + LORA_REG_FREQ_LSB = 0x08, + LORA_REG_PA_CONFIG = 0x09, + LORA_REG_PA_RAMP = 0x0A, + LORA_REG_OVER_CURRENT_PROT_CTRL = 0x0B, + LORA_REG_LNA_SETTINGS = 0x0C, + LORA_REG_FIFO_SPI_POINTER = 0x0D, + LORA_REG_FIFO_TX_DATA = 0x0E, + LORA_REG_FIFO_RX_DATA = 0x0F, + LORA_REG_LORA_STATE_FLAGS = 0x10, + LORA_REG_LORA_FLAG_MASK = 0x11, + LORA_REG_INTERMEDIATE_FREQ_MSB = 0x12, + LORA_REG_INTERMEDIATE_FREQ_LSB = 0x13, + LORA_REG_RCV_TIMEOUT_MSB = 0x14, + LORA_REG_RCV_TIMEOUT_LSB = 0x15, + LORA_REG_TRANS_CONFIG = 0x16, + LORA_REG_TRANS_PAYLOAD_LENGTH = 0x17, + LORA_REG_PREAMBLE_SIZE_MSB = 0x18, + LORA_REG_PREAMBLE_SIZE_LSB = 0x19, + LORA_REG_MODULATION_CONFIG = 0x1A, + LORA_REG_RF_MODE = 0x1B, + LORA_REG_FHSS_HOP_PERIOD = 0x1C, + LORA_REG_NUM_RX_BYTES = 0x1D, + LORA_REG_RX_HEADER_INFO = 0x1E, + LORA_REG_NUM_RX_VALID_HEADERS = 0x1F, + LORA_REG_NUM_RX_VALID_PACKETS = 0x20, + LORA_REG_MODEM_STATUS = 0x21, + LORA_REG_SIGNAL_TO_NOISE = 0x22, + LORA_REG_CURRENT_RSSI = 0x23, + LORA_REG_LAST_PACKET_RSSI = 0x24, + LORA_REG_FREQ_HOP_START_CHANNEL = 0x25, + LORA_REG_RX_DATA_POINTER = 0x26, + LORA_REG_DIO_MAPPING_MODE_1 = 0x40, + LORA_REG_DIO_MAPPING_MODE_2 = 0x41, + LORA_REG_ID_VERSION = 0x42, + LORA_REG_TCXO_OR_XTAL = 0x4B, + LORA_REG_PA_SETTINGS = 0x4D, + LORA_REG_FORMER_TEMP = 0x5B, + LORA_REG_AGC_REFERENCE = 0x61, + LORA_REG_AGC_THRESHOLD_1 = 0x62, + LORA_REG_AGC_THRESHOLD_2 = 0x63, + LORA_REG_AGC_THRESHOLD_4 = 0x64 } LORA_REGISTER_ADDR; #endif \ No newline at end of file From 35eec118b6335aaba62d4a4d562b2a2dda7fe7a4 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Tue, 1 Oct 2024 18:20:45 -0700 Subject: [PATCH 17/60] Fix a really, really dumb typeo --- lora/lora.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lora/lora.c b/lora/lora.c index 81dfd14..6809794 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -34,7 +34,7 @@ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ //TODO: Switch pinState to a good enum -void lora_write_cs_pin( bool pinState ) {LORA_SPI +void lora_write_cs_pin( bool pinState ) { /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin high or low.*/ HAL_GPIO_WritePin( LORA_NSS_PORT, pinState ); From 11da10e2d81392ab4721a28c2ee68bbcab4e28da Mon Sep 17 00:00:00 2001 From: niekky Date: Tue, 1 Oct 2024 19:02:26 -0700 Subject: [PATCH 18/60] massive code reviewed by Nick --- lora/lora.c | 116 ++++++++++++++++++++++++++++------------------------ lora/lora.h | 15 ++++++- 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 6809794..a216170 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -9,12 +9,9 @@ * *******************************************************************************/ -#include "stm32h7xx_hal.h" /*------------------------------------------------------------------------------ Standard Includes ------------------------------------------------------------------------------*/ -#include - /*------------------------------------------------------------------------------ MCU Pins @@ -28,40 +25,55 @@ /*------------------------------------------------------------------------------ Project Inlcudes ------------------------------------------------------------------------------*/ -#include lora.h +#include "lora.h" +#include "main.h" /*------------------------------------------------------------------------------ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ //TODO: Switch pinState to a good enum -void lora_write_cs_pin( bool pinState ) { +void lora_write_cs_pin( CS_STATUS pinState ) { /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin high or low.*/ - HAL_GPIO_WritePin( LORA_NSS_PORT, pinState ); + HAL_GPIO_WritePin( LORA_NSS_PORT, LORA_NSS_PIN, pinState ); } -void lora_spi_receive( uint8_t *read_buffer[2] ) { +LORA_STATUS lora_spi_receive( uint8_t read_buffer[] ) { + LORA_STATUS status; + /* Takes pointer to the read buffer. and puts output there */ - read_buffer = HAL_SPI_Receive( &(hspi4), &(read_buffer), 2, HAL_DEFAULT_TIMEOUT ); + status = HAL_SPI_Receive( &(hspi4), &read_buffer[0], 2, HAL_DEFAULT_TIMEOUT ); + + if (status == LORA_OK){ + return LORA_OK; + } else return LORA_FAIL; } -void lora_spi_transmit( LORA_REGISTER_ADDR register, uint8_t data ) { +LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { + LORA_STATUS status; + // TODO: Actually make this return something /* Takes register and data to write (1 byte) and writes that register. */ - uint8_t transmitBuffer[2] = { register, data }; - HAL_SPI_Transmit( &(hspi4), &transmitBuffer, 2, HAL_DEFAULT_TIMEOUT); -} - -uint8_t lora_spi_get_register( LORA_REGISTER_ADDR lora_register ) { - uint8_t read_buffer[2]; + uint8_t transmitBuffer[2] = { reg, data }; + status = HAL_SPI_Transmit( &(hspi4), &transmitBuffer[0], 2, HAL_DEFAULT_TIMEOUT); - lora_spi_transmit( (lora_register | 0b00000000), 0b00000000 ); + if (status == LORA_OK){ + return LORA_OK; + } else return LORA_FAIL; +} - lora_spi_receive( &read_buffer ); - return read_buffer[2]; +LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData) { + LORA_STATUS transmit_status, receive_status; + + transmit_status = lora_spi_transmit( (lora_register | 0b00000000), 0b00000000 ); + receive_status = lora_spi_receive( ®Data[0] ); + if (transmit_status + receive_status == 0){ + return LORA_OK; + } else return LORA_FAIL; } +// Update this - nick void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { lora_spi_transmit( (lora_register | 0b10000000), data ); } @@ -69,41 +81,39 @@ void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { /*------------------------------------------------------------------------------ Function to set the mode of the chip ------------------------------------------------------------------------------*/ - -void lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { - /* chip_mode should be one of the following 3-bit variables defined in lora.h - #define LORA_SLEEP_MODE 0b000 - #define LORA_STANDBY_MODE 0b001 - #define LORA_FREQ_SYNTH_TX_MODE 0b010 - #define LORA_TRANSMIT_MODE 0b011 - #define LORA_FREQ_SYNTH_RX_MODE 0b100 - #define LORA_RX_CONTINUOUS_MODE 0b101 - #define LORA_RX_SINGLE_MODE 0b111 - */ - // I may give this function a return type in the future to check success of operation. - // Also, may need to be updated based on pin definitions after those are fixed. - - // Pull chip select low - lora_write_cs_pin( GPIO_PIN_SET ); - - // Get initial value of the operation mode register - uint8_t operation_mode_register = lora_spi_get_register( LORA_REG_OPERATION_MODE ); - - // Shift the chip mode bits to be the first 3 bits of the sequence - uint8_t shifted_chip_mode = (chip_mode << 0b00000); - - // Change the value of the chip register to set it to the suggested chip mode - uint8_t new_opmode_register = (operation_mode_register | chip_mode); - - // Write new bit - lora_spi_set_register( LORA_REG_OPERATION_MODE, new_opmode_register );LORA_REG_ - - // Bring chip select back high - lora_write_cs_pin( GPIO_PIN_RESET ); -} +// void lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { +// /* chip_mode should be one of the following 3-bit variables defined in lora.h +// #define LORA_SLEEP_MODE 0b000 +// #define LORA_STANDBY_MODE 0b001 +// #define LORA_FREQ_SYNTH_TX_MODE 0b010 +// #define LORA_TRANSMIT_MODE 0b011 +// #define LORA_FREQ_SYNTH_RX_MODE 0b100 +// #define LORA_RX_CONTINUOUS_MODE 0b101 +// #define LORA_RX_SINGLE_MODE 0b111 +// */ +// // I may give this function a return type in the future to check success of operation. +// // Also, may need to be updated based on pin definitions after those are fixed. + +// // Pull chip select low +// lora_write_cs_pin( GPIO_PIN_SET ); + +// // Get initial value of the operation mode register +// uint8_t operation_mode_register = lora_spi_get_register( LORA_REG_OPERATION_MODE ); + +// // Shift the chip mode bits to be the first 3 bits of the sequence +// uint8_t shifted_chip_mode = (chip_mode << 0b00000); + +// // Change the value of the chip register to set it to the suggested chip mode +// uint8_t new_opmode_register = (operation_mode_register | chip_mode); + +// // Write new bit +// lora_spi_set_register( LORA_REG_OPERATION_MODE, new_opmode_register );LORA_REG_ + +// // Bring chip select back high +// lora_write_cs_pin( GPIO_PIN_RESET ); +// } // Get the device chip ID -uint8_t lora_get_device_id() { - uint8_t[2] chip_id_packet = lora_spi_get_register( LORA_REG_ID_VERSION ); - return chip_id_packet[1]; +void lora_get_device_id(uint8_t* packet) { + lora_spi_get_register( LORA_REG_ID_VERSION, &packet[0]); } \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index 42dd864..c5470dc 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -13,7 +13,6 @@ #define LORA_H /* Project includes */ -#include "sensor.h" /* Operation Mode Register Values */ /* These are just random parts of the operation register that may or not get used @@ -38,6 +37,16 @@ typedef enum LORA_CHIPMODE { LORA_RX_SINGLE_MODE = 0b111, } LORA_CHIPMODE; +typedef enum _LORA_STATUS { + LORA_OK = 0, + LORA_FAIL +} LORA_STATUS; + +typedef enum _CS_STATUS { + CS_LOW = 0, + CS_HIGH +} CS_STATUS; + /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) Note: as we are using LoRa, the FSK opcodes are not included*/ typedef enum LORA_REGISTER_ADDR { @@ -88,4 +97,8 @@ typedef enum LORA_REGISTER_ADDR { LORA_REG_AGC_THRESHOLD_4 = 0x64 } LORA_REGISTER_ADDR; +LORA_STATUS lora_spi_receive( uint8_t read_buffer[] ); + +LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR register, uint8_t data ); + #endif \ No newline at end of file From 9e9f087a96ece74d8c16ba321fc36f5e8a796d08 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Tue, 1 Oct 2024 20:10:30 -0700 Subject: [PATCH 19/60] Add lora_get_device_id to header file --- lora/lora.c | 2 ++ lora/lora.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lora/lora.c b/lora/lora.c index a216170..2ad03ba 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -115,5 +115,7 @@ void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { // Get the device chip ID void lora_get_device_id(uint8_t* packet) { + lora_write_cs_pin(CS_HIGH); lora_spi_get_register( LORA_REG_ID_VERSION, &packet[0]); + lora_write_cs_pin(CS_LOW); } \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index c5470dc..0b73d39 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -101,4 +101,6 @@ LORA_STATUS lora_spi_receive( uint8_t read_buffer[] ); LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR register, uint8_t data ); +void lora_get_device_id(uint8_t* packet); + #endif \ No newline at end of file From a9810d11a81dd20b1f33f6a2de997d123881fa3a Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 8 Nov 2024 18:18:05 -0700 Subject: [PATCH 20/60] Debug code for LORA --- lora/lora.c | 18 ++++++++++++++++-- lora/lora.h | 9 ++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 2ad03ba..3f956d2 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -65,12 +65,26 @@ LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData) { LORA_STATUS transmit_status, receive_status; + + lora_write_cs_pin( CS_LOW ); - transmit_status = lora_spi_transmit( (lora_register | 0b00000000), 0b00000000 ); + transmit_status = lora_spi_transmit( (lora_register | 0b00000000), 0b00000000 ); // The problem starts here receive_status = lora_spi_receive( ®Data[0] ); + + lora_write_cs_pin( CS_HIGH ); + + // I've temporarily added RECEIVE_FAIL and TRANSMIT_FAIL to the enum to be able to pinpoint issues + // This will be removed in the final code, and this function will only be able to output + // LORA_OK or LORA_FAIL if (transmit_status + receive_status == 0){ return LORA_OK; - } else return LORA_FAIL; + } /* else return LORA_FAIL; */ else if( transmit_status == LORA_FAIL ) { + return LORA_TRANSMIT_FAIL; + } else if( receive_status == LORA_RECEIVE_FAIL ) { + return LORA_RECEIVE_FAIL; + } else { + return LORA_FAIL; + } } // Update this - nick diff --git a/lora/lora.h b/lora/lora.h index 0b73d39..c68043c 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -37,14 +37,17 @@ typedef enum LORA_CHIPMODE { LORA_RX_SINGLE_MODE = 0b111, } LORA_CHIPMODE; -typedef enum _LORA_STATUS { +typedef enum LORA_STATUS { LORA_OK = 0, - LORA_FAIL + LORA_FAIL, + // Temporary enum additions to distinguish between transmit and receive failures + LORA_TRANSMIT_FAIL, + LORA_RECEIVE_FAIL } LORA_STATUS; typedef enum _CS_STATUS { CS_LOW = 0, - CS_HIGH + CS_HIGH =1 } CS_STATUS; /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) From 62a0c5809b91de3fb3c745b218627b95424248be Mon Sep 17 00:00:00 2001 From: Drew Date: Mon, 16 Dec 2024 15:20:35 -0700 Subject: [PATCH 21/60] Clean up a bit before merge --- lora/lora.c | 4 ++-- lora/lora.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 3f956d2..dd20575 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -88,8 +88,8 @@ LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* re } // Update this - nick -void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { - lora_spi_transmit( (lora_register | 0b10000000), data ); +LORA_STATUS lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { + return lora_spi_transmit( (lora_register | 0b10000000), data ); } /*------------------------------------------------------------------------------ diff --git a/lora/lora.h b/lora/lora.h index c68043c..50fccc3 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -47,7 +47,7 @@ typedef enum LORA_STATUS { typedef enum _CS_STATUS { CS_LOW = 0, - CS_HIGH =1 + CS_HIGH = 1 } CS_STATUS; /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) From d49ff9667dbab8d1a78aa0ff9e60a56e3e87730a Mon Sep 17 00:00:00 2001 From: Drew Date: Mon, 16 Dec 2024 15:34:54 -0700 Subject: [PATCH 22/60] Revert "Clean up a bit before merge" This reverts commit 62a0c5809b91de3fb3c745b218627b95424248be. --- lora/lora.c | 4 ++-- lora/lora.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index dd20575..3f956d2 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -88,8 +88,8 @@ LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* re } // Update this - nick -LORA_STATUS lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { - return lora_spi_transmit( (lora_register | 0b10000000), data ); +void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { + lora_spi_transmit( (lora_register | 0b10000000), data ); } /*------------------------------------------------------------------------------ diff --git a/lora/lora.h b/lora/lora.h index 50fccc3..c68043c 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -47,7 +47,7 @@ typedef enum LORA_STATUS { typedef enum _CS_STATUS { CS_LOW = 0, - CS_HIGH = 1 + CS_HIGH =1 } CS_STATUS; /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) From 17e47ecad6095167bd6291700129279e8370fbee Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Sat, 23 Nov 2024 15:44:17 -0700 Subject: [PATCH 23/60] Fiddle around with chipmode some more --- lora/lora.c | 13 ++++++++----- lora/lora.h | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 3f956d2..cf46803 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -35,7 +35,11 @@ void lora_write_cs_pin( CS_STATUS pinState ) { /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin high or low.*/ - HAL_GPIO_WritePin( LORA_NSS_PORT, LORA_NSS_PIN, pinState ); + if( pinState == CS_HIGH ) { + HAL_GPIO_WritePin( LORA_NSS_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); + } else { + HAL_GPIO_WritePin( LORA_NSS_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); + } } LORA_STATUS lora_spi_receive( uint8_t read_buffer[] ) { @@ -69,6 +73,7 @@ LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* re lora_write_cs_pin( CS_LOW ); transmit_status = lora_spi_transmit( (lora_register | 0b00000000), 0b00000000 ); // The problem starts here + transmit_status = LORA_OK; receive_status = lora_spi_receive( ®Data[0] ); lora_write_cs_pin( CS_HIGH ); @@ -128,8 +133,6 @@ void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { // } // Get the device chip ID -void lora_get_device_id(uint8_t* packet) { - lora_write_cs_pin(CS_HIGH); - lora_spi_get_register( LORA_REG_ID_VERSION, &packet[0]); - lora_write_cs_pin(CS_LOW); +LORA_STATUS lora_get_device_id(uint8_t* packet) { + return lora_spi_get_register( LORA_REG_ID_VERSION, &packet[0]); } \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index c68043c..4f6c19b 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -47,7 +47,7 @@ typedef enum LORA_STATUS { typedef enum _CS_STATUS { CS_LOW = 0, - CS_HIGH =1 + CS_HIGH } CS_STATUS; /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) @@ -104,6 +104,6 @@ LORA_STATUS lora_spi_receive( uint8_t read_buffer[] ); LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR register, uint8_t data ); -void lora_get_device_id(uint8_t* packet); +LORA_STATUS lora_get_device_id(uint8_t* packet); #endif \ No newline at end of file From 1d08b020e78b0ffd8230bac5bd1b38b025401228 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Mon, 16 Dec 2024 15:37:30 -0700 Subject: [PATCH 24/60] Add return value to lora_spii_set_register --- lora/lora.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index cf46803..34d4957 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -92,9 +92,9 @@ LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* re } } -// Update this - nick -void lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { - lora_spi_transmit( (lora_register | 0b10000000), data ); + +LORA_STATUS lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { + return lora_spi_transmit( (lora_register | 0b10000000), data ); } /*------------------------------------------------------------------------------ From 77cce78fc0ccc25a4a0266bc12bba5c4f8c525bd Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Mon, 16 Dec 2024 15:40:56 -0700 Subject: [PATCH 25/60] Add a comment on why I use the HAL enums in CS pin write function --- lora/lora.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lora/lora.c b/lora/lora.c index 34d4957..c136b88 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -34,7 +34,8 @@ //TODO: Switch pinState to a good enum void lora_write_cs_pin( CS_STATUS pinState ) { /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin - high or low.*/ + high or low. I use the HAL enums because that's what our flash module + does as well. */ if( pinState == CS_HIGH ) { HAL_GPIO_WritePin( LORA_NSS_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); } else { From 0a8d21395fde8014b830ca8b8c2a232ca385f3e1 Mon Sep 17 00:00:00 2001 From: niekky Date: Wed, 15 Jan 2025 20:04:45 -0700 Subject: [PATCH 26/60] - Fixed incorrect datatype - Deleted old LoRa code --- lora/lora.c | 24 +- lora_sx1276/LoRa.c | 649 --------------------------------------------- lora_sx1276/LoRa.h | 391 --------------------------- 3 files changed, 12 insertions(+), 1052 deletions(-) delete mode 100644 lora_sx1276/LoRa.c delete mode 100644 lora_sx1276/LoRa.h diff --git a/lora/lora.c b/lora/lora.c index c136b88..511fd1a 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -37,27 +37,27 @@ void lora_write_cs_pin( CS_STATUS pinState ) { high or low. I use the HAL enums because that's what our flash module does as well. */ if( pinState == CS_HIGH ) { - HAL_GPIO_WritePin( LORA_NSS_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); + HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); } else { - HAL_GPIO_WritePin( LORA_NSS_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); + HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); } } -LORA_STATUS lora_spi_receive( uint8_t read_buffer[] ) { - LORA_STATUS status; +LORA_STATUS lora_spi_receive( uint8_t* read_buffer_ptr ) { + HAL_StatusTypeDef status; /* Takes pointer to the read buffer. and puts output there */ - status = HAL_SPI_Receive( &(hspi4), &read_buffer[0], 2, HAL_DEFAULT_TIMEOUT ); + status = HAL_SPI_Receive( &(hspi4), &read_buffer_ptr[0], 2, HAL_DEFAULT_TIMEOUT ); if (status == LORA_OK){ return LORA_OK; - } else return LORA_FAIL; + } else + return LORA_FAIL; } LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { - LORA_STATUS status; + HAL_StatusTypeDef status; - // TODO: Actually make this return something /* Takes register and data to write (1 byte) and writes that register. */ uint8_t transmitBuffer[2] = { reg, data }; status = HAL_SPI_Transmit( &(hspi4), &transmitBuffer[0], 2, HAL_DEFAULT_TIMEOUT); @@ -82,9 +82,9 @@ LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* re // I've temporarily added RECEIVE_FAIL and TRANSMIT_FAIL to the enum to be able to pinpoint issues // This will be removed in the final code, and this function will only be able to output // LORA_OK or LORA_FAIL - if (transmit_status + receive_status == 0){ + if (transmit_status | receive_status == 0){ return LORA_OK; - } /* else return LORA_FAIL; */ else if( transmit_status == LORA_FAIL ) { + } else if( transmit_status == LORA_FAIL ) { return LORA_TRANSMIT_FAIL; } else if( receive_status == LORA_RECEIVE_FAIL ) { return LORA_RECEIVE_FAIL; @@ -134,6 +134,6 @@ LORA_STATUS lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t dat // } // Get the device chip ID -LORA_STATUS lora_get_device_id(uint8_t* packet) { - return lora_spi_get_register( LORA_REG_ID_VERSION, &packet[0]); +LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr) { + return lora_spi_get_register( LORA_REG_ID_VERSION, &buffer_ptr[0]); } \ No newline at end of file diff --git a/lora_sx1276/LoRa.c b/lora_sx1276/LoRa.c deleted file mode 100644 index ced81d4..0000000 --- a/lora_sx1276/LoRa.c +++ /dev/null @@ -1,649 +0,0 @@ -// Copyright (c) Konstantin Belyalov. All rights reserved. -// Licensed under the MIT license. -#include "LoRa.h" - -// Debugging support -// To enable debug information add -// #define LORA_DEBUG -// to main.h -#ifdef LORA_DEBUG -#define DEBUGF(msg, ...) printf(const char *fmt, ##__VA_ARGS__); -#else -#define DEBUGF(msg, ...) -#endif - -// SPI helpers // - -// Reads single register -static uint8_t read_register(lora_sx1276 *lora, uint8_t address) -{ - uint8_t value = 0; - - // 7bit controls read/write mode - CLEAR_BIT(address, BIT_7); - - // Start SPI transaction - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); - // Transmit reg address, then receive it value - uint32_t res1 = HAL_SPI_Transmit(lora->spi, &address, 1, lora->spi_timeout); - uint32_t res2 = HAL_SPI_Receive(lora->spi, &value, 1, lora->spi_timeout); - // End SPI transaction - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); - - if (res1 != HAL_OK || res2 != HAL_OK) { - DEBUGF("SPI transmit/receive failed (%d %d)", res1, res2); - } - - return value; -} - -// Writes single register -static void write_register(lora_sx1276 *lora, uint8_t address, uint8_t value) -{ - // 7bit controls read/write mode - SET_BIT(address, BIT_7); - - // Reg address + its new value - uint16_t payload = (value << 8) | address; - - // Start SPI transaction, send address + value - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); - uint32_t res = HAL_SPI_Transmit(lora->spi, (uint8_t*)&payload, 2, lora->spi_timeout); - // End SPI transaction - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); - - if (res != HAL_OK) { - DEBUGF("SPI transmit failed: %d", res); - } -} - -// Copies bytes from buffer into radio FIFO given len length -static void write_fifo(lora_sx1276 *lora, uint8_t *buffer, uint8_t len, uint8_t mode) -{ - uint8_t address = REG_FIFO | BIT_7; - - // Start SPI transaction, send address - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); - uint32_t res1 = HAL_SPI_Transmit(lora->spi, &address, 1, lora->spi_timeout); - if (mode == TRANSFER_MODE_DMA) { - HAL_SPI_Transmit_DMA(lora->spi, buffer, len); - // Intentionally leave SPI active - let DMA finish transfer - return; - } - uint32_t res2 = HAL_SPI_Transmit(lora->spi, buffer, len, lora->spi_timeout); - // End SPI transaction - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); - - if (res1 != HAL_OK || res2 != HAL_OK) { - DEBUGF("SPI transmit failed"); - } -} - -// Reads data "len" size from FIFO into buffer -static void read_fifo(lora_sx1276 *lora, uint8_t *buffer, uint8_t len, uint8_t mode) -{ - uint8_t address = REG_FIFO; - - // Start SPI transaction, send address - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_RESET); - uint32_t res1 = HAL_SPI_Transmit(lora->spi, &address, 1, lora->spi_timeout); - uint32_t res2; - if (mode == TRANSFER_MODE_DMA) { - res2 = HAL_SPI_Receive_DMA(lora->spi, buffer, len); - // Do not end SPI here - must be done externally when DMA done - } else { - res2 = HAL_SPI_Receive(lora->spi, buffer, len, lora->spi_timeout); - // End SPI transaction - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); - } - - if (res1 != HAL_OK || res2 != HAL_OK) { - DEBUGF("SPI receive/transmit failed"); - } -} - -static void set_mode(lora_sx1276 *lora, uint8_t mode) -{ - write_register(lora, REG_OP_MODE, OPMODE_LONG_RANGE_MODE | mode); -} - -// Set Overload Current Protection -static void set_OCP(lora_sx1276 *lora, uint8_t imax) -{ - uint8_t value; - - // Minimum available current is 45mA, maximum 240mA - // As per page 80 of datasheet - if (imax < 45) { - imax = 45; - } - if (imax > 240) { - imax = 240; - } - - if (imax < 130) { - value = (imax - 45) / 5; - } else { - value = (imax + 30) / 10; - } - - write_register(lora, REG_OCP, OCP_ON | value); -} - -static void set_low_data_rate_optimization(lora_sx1276 *lora) -{ - assert_param(lora); - - // Read current signal bandwidth - uint64_t bandwidth = read_register(lora, REG_MODEM_CONFIG_1) >> 4; - // Read current spreading factor - uint8_t sf = read_register(lora, REG_MODEM_CONFIG_2) >> 4; - - uint8_t mc3 = MC3_AGCAUTO; - - if (sf >= 11 && bandwidth == LORA_BANDWIDTH_125_KHZ) { - mc3 |= MC3_MOBILE_NODE; - } - - write_register(lora, REG_MODEM_CONFIG_3, mc3); -} - -void lora_mode_sleep(lora_sx1276 *lora) -{ - assert_param(lora); - - set_mode(lora, OPMODE_SLEEP); -} - -void lora_mode_receive_continuous(lora_sx1276 *lora) -{ - assert_param(lora); - - // Update base FIFO address for incoming packets - write_register(lora, REG_FIFO_RX_BASE_ADDR, lora->rx_base_addr); - // Clear all RX related IRQs - write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); - - set_mode(lora, OPMODE_RX_CONTINUOUS); -} - -void lora_mode_receive_single(lora_sx1276 *lora) -{ - assert_param(lora); - - // Update base FIFO address for incoming packets - write_register(lora, REG_FIFO_RX_BASE_ADDR, lora->rx_base_addr); - // Clear all RX related IRQs - write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); - - set_mode(lora, OPMODE_RX_SINGLE); -} - -void lora_mode_standby(lora_sx1276 *lora) -{ - assert_param(lora); - - set_mode(lora, OPMODE_STDBY); -} - -void lora_set_implicit_header_mode(lora_sx1276 *lora) -{ - assert_param(lora); - - uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); - mc1 |= MC1_IMPLICIT_HEADER_MODE; - write_register(lora, REG_MODEM_CONFIG_1, mc1); -} - -void lora_set_explicit_header_mode(lora_sx1276 *lora) -{ - assert_param(lora); - - uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); - mc1 &= ~MC1_IMPLICIT_HEADER_MODE; - write_register(lora, REG_MODEM_CONFIG_1, mc1); -} - -void lora_set_tx_power(lora_sx1276 *lora, uint8_t level) -{ - assert_param(lora); - - if (lora->pa_mode == LORA_PA_OUTPUT_RFO) { - // RFO pin - assert_param(level <= 15); - if (level > 15) { - level = 15; - } - // 7 bit -> PaSelect: 0 for RFO --- = 0x70 - // 6-4 bits -> MaxPower (select all) --^ - // 3-0 bits -> Output power, dB (max 15) - write_register(lora, REG_PA_CONFIG, 0x70 | level); - } else { - // PA BOOST pin, from datasheet (Power Amplifier): - // Pout=17-(15-OutputPower) - assert_param(level <= 20 && level >= 2); - if (level > 20) { - level = 20; - } - if (level < 2) { - level = 2; - } - // Module power consumption from datasheet: - // RFOP = +20 dBm, on PA_BOOST -> 120mA - // RFOP = +17 dBm, on PA_BOOST -> 87mA - if (level > 17) { - // PA_DAC_HIGH_POWER operation changes last 3 OutputPower modes to: - // 13 -> 18dB, 14 -> 19dB, 15 -> 20dB - // So subtract 3 from level - level -= 3; - // Enable High Power mode - write_register(lora, REG_PA_DAC, PA_DAC_HIGH_POWER); - // Limit maximum current to 140mA (+20mA to datasheet value to be sure) - set_OCP(lora, 140); - } else { - // Enable half power mode (default) - write_register(lora, REG_PA_DAC, PA_DAC_HALF_POWER); - // Limit maximum current to 97mA (+10mA to datasheet value to be sure) - set_OCP(lora, 97); - } - // Minimum power level is 2 which is 0 for chip - level -= 2; - // 7 bit -> PaSelect: 1 for PA_BOOST - write_register(lora, REG_PA_CONFIG, BIT_7 | level); - } -} - -void lora_set_frequency(lora_sx1276 *lora, uint64_t freq) -{ - assert_param(lora); - - // From datasheet: FREQ = (FRF * 32 Mhz) / (2 ^ 19) - uint64_t frf = (freq << 19) / (32 * MHZ); - - write_register(lora, REG_FRF_MSB, frf >> 16); - write_register(lora, REG_FRF_MID, (frf & 0xff00) >> 8); - write_register(lora, REG_FRF_LSB, frf & 0xff); -} - -int8_t lora_packet_rssi(lora_sx1276 *lora) -{ - assert_param(lora); - - uint8_t rssi = read_register(lora, REG_PKT_RSSI_VALUE); - - return lora->frequency < (868 * MHZ) ? rssi - 164 : rssi - 157; -} - -uint8_t lora_packet_snr(lora_sx1276 *lora) -{ - assert_param(lora); - - uint8_t snr = read_register(lora, REG_PKT_SNR_VALUE); - - return snr / 5; -} - -void lora_set_signal_bandwidth(lora_sx1276 *lora, uint64_t bw) -{ - assert_param(lora && bw < LORA_BW_LAST); - - // REG_MODEM_CONFIG_1 has 2 more parameters: - // Coding rate / Header mode, so read them before set bandwidth - uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); - // Signal bandwidth uses 4-7 bits of config - mc1 = (mc1 & 0x0F) | bw << 4; - write_register(lora, REG_MODEM_CONFIG_1, mc1); - - set_low_data_rate_optimization(lora); -} - -void lora_set_spreading_factor(lora_sx1276 *lora, uint8_t sf) -{ - assert_param(lora && sf <= 12 && sf >=6); - - if (sf < 6) { - sf = 6; - } else if (sf > 12) { - sf = 12; - } - - if (sf == 6) { - write_register(lora, REG_DETECTION_OPTIMIZE, 0xc5); - write_register(lora, REG_DETECTION_THRESHOLD, 0x0c); - } else { - write_register(lora, REG_DETECTION_OPTIMIZE, 0xc3); - write_register(lora, REG_DETECTION_THRESHOLD, 0x0a); - } - // Set new spread factor - uint8_t mc2 = read_register(lora, REG_MODEM_CONFIG_2); - mc2 = (mc2 & 0x0F) | (sf << 4); - // uint8_t new_config = (current_config & 0x0f) | ((sf << 4) & 0xf0); - write_register(lora, REG_MODEM_CONFIG_2, mc2); - - set_low_data_rate_optimization(lora); -} - -void lora_set_crc(lora_sx1276 *lora, uint8_t enable) -{ - assert_param(lora); - - uint8_t mc2 = read_register(lora, REG_MODEM_CONFIG_2); - - if (enable) { - mc2 |= MC2_CRC_ON; - } else { - mc2 &= ~MC2_CRC_ON; - } - - write_register(lora, REG_MODEM_CONFIG_2, mc2); -} - -void lora_set_coding_rate(lora_sx1276 *lora, uint8_t rate) -{ - assert_param(lora); - - uint8_t mc1 = read_register(lora, REG_MODEM_CONFIG_1); - - // coding rate bits are 1-3 in modem config 1 register - mc1 |= rate << 1; - write_register(lora, REG_MODEM_CONFIG_1, mc1); -} - -void lora_set_preamble_length(lora_sx1276 *lora, uint16_t len) -{ - assert_param(lora); - - write_register(lora, REG_PREAMBLE_MSB, len >> 8); - write_register(lora, REG_PREAMBLE_LSB, len & 0xf); -} - -uint8_t lora_version(lora_sx1276 *lora) -{ - assert_param(lora); - - return read_register(lora, REG_VERSION); -} - -uint8_t lora_is_transmitting(lora_sx1276 *lora) -{ - assert_param(lora); - - uint8_t opmode = read_register(lora, REG_OP_MODE); - - return (opmode & OPMODE_TX) == OPMODE_TX ? LORA_BUSY : LORA_OK; -} - -static uint8_t lora_send_packet_base(lora_sx1276 *lora, uint8_t *data, uint8_t data_len, uint8_t mode) -{ - assert_param(lora && data && data_len > 0); - - if (lora_is_transmitting(lora)) { - return LORA_BUSY; - } - - // Wakeup radio because of FIFO is only available in STANDBY mode - set_mode(lora, OPMODE_STDBY); - - // Clear TX IRQ flag, to be sure - lora_clear_interrupt_tx_done(lora); - - // Set FIFO pointer to the beginning of the buffer - write_register(lora, REG_FIFO_ADDR_PTR, lora->tx_base_addr); - write_register(lora, REG_FIFO_TX_BASE_ADDR, lora->tx_base_addr); - write_register(lora, REG_PAYLOAD_LENGTH, data_len); - - // Copy packet into radio FIFO - write_fifo(lora, data, data_len, mode); - if (mode == TRANSFER_MODE_DMA) { - return LORA_OK; - } - - // Put radio in TX mode - packet will be transmitted ASAP - set_mode(lora, OPMODE_TX); - return LORA_OK; -} - -uint8_t lora_send_packet(lora_sx1276 *lora, uint8_t *data, uint8_t data_len) -{ - return lora_send_packet_base(lora, data, data_len, TRANSFER_MODE_BLOCKING); -} - -uint8_t lora_send_packet_dma_start(lora_sx1276 *lora, uint8_t *data, uint8_t data_len) -{ - return lora_send_packet_base(lora, data, data_len, TRANSFER_MODE_DMA); -} - -// Finish packet send initiated by lora_send_packet_dma_start() -void lora_send_packet_dma_complete(lora_sx1276 *lora) -{ - // End transfer - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); - // Send packet - set_mode(lora, OPMODE_TX); -} - -uint8_t lora_send_packet_blocking(lora_sx1276 *lora, uint8_t *data, uint8_t data_len, uint32_t timeout) -{ - assert_param(lora && data && data_len > 0 && timeout > 0); - - uint8_t res = lora_send_packet(lora, data, data_len); - - if (res == LORA_OK) { - // Wait until packet gets transmitted - uint32_t elapsed = 0; - while (elapsed < timeout) { - uint8_t state = read_register(lora, REG_IRQ_FLAGS); - if (state & IRQ_FLAGS_TX_DONE) { - // Packet sent - write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_TX_DONE); - return LORA_OK; - } - HAL_Delay(1); - elapsed++; - } - } - - return LORA_TIMEOUT; -} - -void lora_set_rx_symbol_timeout(lora_sx1276 *lora, uint16_t symbols) -{ - assert_param(lora && symbols <= 1024 && symbols >= 4); - - if (symbols < 4) { - symbols = 4; - } - if (symbols > 1023) { - symbols = 1024; - } - - write_register(lora, REG_SYMB_TIMEOUT_LSB, symbols & 0xf); - if (symbols > 255) { - // MSB (2 first bits of config2) - uint8_t mc2 = read_register(lora, REG_MODEM_CONFIG_2); - mc2 |= symbols >> 8; - write_register(lora, REG_MODEM_CONFIG_2, mc2); - } -} - -uint8_t lora_is_packet_available(lora_sx1276 *lora) -{ - assert_param(lora); - - uint8_t irqs = read_register(lora, REG_IRQ_FLAGS); - - // In case of Single receive mode RX_TIMEOUT will be issued - return irqs & (IRQ_FLAGS_RX_DONE | IRQ_FLAGS_RX_TIMEOUT); -} - -uint8_t lora_pending_packet_length(lora_sx1276 *lora) -{ - uint8_t len; - - // Query for current header mode - implicit / explicit - uint8_t implicit = read_register(lora, REG_MODEM_CONFIG_1) & MC1_IMPLICIT_HEADER_MODE; - if (implicit) { - len = read_register(lora, REG_PAYLOAD_LENGTH); - } else { - len = read_register(lora, REG_RX_NB_BYTES); - } - - return len; -} - - -static uint8_t lora_receive_packet_base(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error, uint8_t mode) -{ - assert_param(lora && buffer && buffer_len > 0); - - uint8_t res = LORA_EMPTY; - uint8_t len = 0; - - // Read/Reset IRQs - uint8_t state = read_register(lora, REG_IRQ_FLAGS); - write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); - - if (state & IRQ_FLAGS_RX_TIMEOUT) { - DEBUGF("timeout"); - res = LORA_TIMEOUT; - goto done; - } - - if (state & IRQ_FLAGS_RX_DONE) { - if (!(state & IRQ_FLAGS_VALID_HEADER)) { - DEBUGF("invalid header"); - res = LORA_INVALID_HEADER; - goto done; - } - // Packet has been received - if (state & IRQ_FLAGS_PAYLOAD_CRC_ERROR) { - DEBUGF("CRC error"); - res = LORA_CRC_ERROR; - goto done; - } - // Query for current header mode - implicit / explicit - len = lora_pending_packet_length(lora); - // Set FIFO to beginning of the packet - uint8_t offset = read_register(lora, REG_FIFO_RX_CURRENT_ADDR); - write_register(lora, REG_FIFO_ADDR_PTR, offset); - // Read payload - read_fifo(lora, buffer, len, mode); - res = LORA_OK; - } - -done: - if (error) { - *error = res; - } - - return len; -} - -uint8_t lora_receive_packet(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error) -{ - return lora_receive_packet_base(lora, buffer, buffer_len, error, TRANSFER_MODE_BLOCKING); -} - -uint8_t lora_receive_packet_dma_start(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error) -{ - return lora_receive_packet_base(lora, buffer, buffer_len, error, TRANSFER_MODE_DMA); -} - -void lora_receive_packet_dma_complete(lora_sx1276 *lora) -{ - // Nothing to do expect - just end SPI transaction - HAL_GPIO_WritePin(lora->nss_port, lora->nss_pin, GPIO_PIN_SET); -} - -uint8_t lora_receive_packet_blocking(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, - uint32_t timeout, uint8_t *error) -{ - assert_param(lora && buffer && buffer_len > 0); - - uint32_t elapsed = 0; - - // Wait up to timeout for packet - while (elapsed < timeout) { - if (lora_is_packet_available(lora)) { - break; - } - HAL_Delay(1); - elapsed++; - } - - return lora_receive_packet(lora, buffer, buffer_len, error); -} - -void lora_enable_interrupt_rx_done(lora_sx1276 *lora) -{ - // Table 63 DIO Mapping LoRaTM Mode: - // 00 -> (DIO0 rx_done) - // DIO0 uses 6-7 bits of DIO_MAPPING_1 - write_register(lora, REG_DIO_MAPPING_1, 0x00); -} - -void lora_enable_interrupt_tx_done(lora_sx1276 *lora) -{ - // Table 63 DIO Mapping LoRaTM Mode: - // 01 -> (DIO0 tx_done) - // DIO0 uses 6-7 bits of DIO_MAPPING_1 - write_register(lora, REG_DIO_MAPPING_1, 0x40); -} - -void lora_clear_interrupt_tx_done(lora_sx1276 *lora) -{ - write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_TX_DONE); -} - -void lora_clear_interrupt_rx_all(lora_sx1276 *lora) -{ - write_register(lora, REG_IRQ_FLAGS, IRQ_FLAGS_RX_ALL); -} - - -uint8_t lora_init(lora_sx1276 *lora, SPI_HandleTypeDef *spi, GPIO_TypeDef *nss_port, - uint16_t nss_pin, uint64_t freq) -{ - assert_param(lora && spi); - - // Init params with default values - lora->spi = spi; - lora->nss_port = nss_port; - lora->nss_pin = nss_pin; - lora->frequency = freq; - lora->pa_mode = LORA_PA_OUTPUT_PA_BOOST; - lora->tx_base_addr = LORA_DEFAULT_TX_ADDR; - lora->rx_base_addr = LORA_DEFAULT_RX_ADDR; - lora->spi_timeout = LORA_DEFAULT_SPI_TIMEOUT; - - // Check version - uint8_t ver = lora_version(lora); - if (ver != LORA_COMPATIBLE_VERSION) { - DEBUGF("Got wrong radio version 0x%x, expected 0x12", ver); - return LORA_ERROR; - } - - // Modem parameters (freq, mode, etc) must be done in SLEEP mode. - lora_mode_sleep(lora); - // Enable LoRa mode (since it can be switched on only in sleep) - lora_mode_sleep(lora); - - // Set frequency - lora_set_frequency(lora, freq); - lora_set_spreading_factor(lora, LORA_DEFAULT_SF); - lora_set_preamble_length(lora, LORA_DEFAULT_PREAMBLE_LEN); - // By default - explicit header mode - lora_set_explicit_header_mode(lora); - // Set LNA boost - uint8_t current_lna = read_register(lora, REG_LNA); - write_register(lora, REG_LNA, current_lna | 0x03); - // Set auto AGC - write_register(lora, REG_MODEM_CONFIG_3, 0x04); - // Set default output power - lora_set_tx_power(lora, LORA_DEFAULT_TX_POWER); - // Set default mode - lora_mode_standby(lora); - - return LORA_OK; -} - diff --git a/lora_sx1276/LoRa.h b/lora_sx1276/LoRa.h deleted file mode 100644 index ea96125..0000000 --- a/lora_sx1276/LoRa.h +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (c) Konstantin Belyalov. All rights reserved. -// Licensed under the MIT license. - -#ifndef __LORA_H -#define __LORA_H - -#include "main.h" - - -// sx1276 registers -#define REG_FIFO 0x00 -#define REG_OP_MODE 0x01 -#define REG_FRF_MSB 0x06 -#define REG_FRF_MID 0x07 -#define REG_FRF_LSB 0x08 -#define REG_PA_CONFIG 0x09 -#define REG_OCP 0x0b -#define REG_LNA 0x0c -#define REG_FIFO_ADDR_PTR 0x0d -#define REG_FIFO_TX_BASE_ADDR 0x0e -#define REG_FIFO_RX_BASE_ADDR 0x0f -#define REG_FIFO_RX_CURRENT_ADDR 0x10 -#define REG_IRQ_FLAGS 0x12 -#define REG_RX_NB_BYTES 0x13 -#define REG_PKT_SNR_VALUE 0x19 -#define REG_PKT_RSSI_VALUE 0x1a -#define REG_MODEM_CONFIG_1 0x1d -#define REG_MODEM_CONFIG_2 0x1e -#define REG_SYMB_TIMEOUT_LSB 0x1f -#define REG_PREAMBLE_MSB 0x20 -#define REG_PREAMBLE_LSB 0x21 -#define REG_PAYLOAD_LENGTH 0x22 -#define REG_MODEM_CONFIG_3 0x26 -#define REG_DETECTION_OPTIMIZE 0x31 -#define REG_DETECTION_THRESHOLD 0x37 -#define REG_DIO_MAPPING_1 0x40 -#define REG_VERSION 0x42 -#define REG_PA_DAC 0x4d - -// modes -#define OPMODE_SLEEP 0x00 -#define OPMODE_STDBY 0x01 -#define OPMODE_TX 0x03 -#define OPMODE_RX_CONTINUOUS 0x05 -#define OPMODE_RX_SINGLE 0x06 -#define OPMODE_LONG_RANGE_MODE 0x80 // (1 << 7) - -// Power Amplifier (PA_DAC) settings -#define PA_DAC_HIGH_POWER 0x87 -#define PA_DAC_HALF_POWER 0x84 - -// Over Current Protection (OCP) config -#define OCP_ON (1 << 5) - -// Modem config register parameters -#define MC1_IMPLICIT_HEADER_MODE (1 << 0) - -#define MC2_CRC_ON (1 << 2) - -#define MC3_AGCAUTO (1 << 2) -#define MC3_MOBILE_NODE (1 << 3) - -// IRQs -#define IRQ_FLAGS_RX_TIMEOUT (1 << 7) -#define IRQ_FLAGS_RX_DONE (1 << 6) -#define IRQ_FLAGS_PAYLOAD_CRC_ERROR (1 << 5) -#define IRQ_FLAGS_VALID_HEADER (1 << 4) -#define IRQ_FLAGS_TX_DONE (1 << 3) -#define IRQ_FLAGS_CAD_DONE (1 << 2) -#define IRQ_FLAGS_FHSSCHANGECHANNEL (1 << 1) -#define IRQ_FLAGS_CAD_DETECTED (1 << 0) -#define IRQ_FLAGS_RX_ALL 0xf0 - -// Just to make it readable -#define BIT_7 (1 << 7) - -#define TRANSFER_MODE_DMA 1 -#define TRANSFER_MODE_BLOCKING 2 - - - -/* LORA SETTING CONFIGURATION */ - -#define LORA_MAX_PACKET_SIZE 128 - -// Operational frequency -#define MHZ 1000000LLU -#define LORA_BASE_FREQUENCY_US (915LLU*MHZ) -#define LORA_BASE_FREQUENCY_EU (868LLU*MHZ) - -// Default settings -#define LORA_DEFAULT_TX_POWER 17 -#define LORA_DEFAULT_SF 7 -#define LORA_DEFAULT_PREAMBLE_LEN 10 -#define LORA_DEFAULT_RX_ADDR 0 -#define LORA_DEFAULT_TX_ADDR 0 -#define LORA_DEFAULT_SPI_TIMEOUT 1000 // ms - -#define LORA_COMPATIBLE_VERSION 0x12U - -// LORA return codes -#define LORA_OK 0 -#define LORA_CRC_ERROR 1 -#define LORA_TIMEOUT 2 -#define LORA_INVALID_HEADER 3 -#define LORA_ERROR 4 -#define LORA_BUSY 5 -#define LORA_EMPTY 6 - -// TX power mode select -#define LORA_PA_OUTPUT_RFO 0 -#define LORA_PA_OUTPUT_PA_BOOST 1 - -// Coding rate -#define LORA_CODING_RATE_4_5 0x08 -#define LORA_CODING_RATE_4_6 0x10 -#define LORA_CODING_RATE_4_7 0x18 -#define LORA_CODING_RATE_4_8 0x20 - -// Signal bandwidth ("spread factor") -enum { - LORA_BANDWIDTH_7_8_KHZ = 0, - LORA_BANDWIDTH_10_4_KHZ, - LORA_BANDWIDTH_15_6_KHZ, - LORA_BANDWIDTH_20_8_KHZ, - LORA_BANDWIDTH_31_25_KHZ, - LORA_BANDWIDTH_41_7_KHZ, - LORA_BANDWIDTH_62_5_KHZ, - LORA_BANDWIDTH_125_KHZ, // default SF - 7 - LORA_BANDWIDTH_250_KHZ, - LORA_BANDWIDTH_500_KHZ, - LORA_BW_LAST, -}; - -// LORA definition -typedef struct { - // SPI parameters - SPI_HandleTypeDef *spi; - GPIO_TypeDef *nss_port; - uint32_t spi_timeout; - // Operating frequency, in Hz - uint32_t frequency; - // Output PIN (module internal, not related to your design) - // Can be one of PA_OUTPUT_PA_BOOST / PA_OUTPUT_RFO - uint32_t pa_mode; - // Base FIFO addresses for RX/TX - uint8_t tx_base_addr; - uint8_t rx_base_addr; - - uint16_t nss_pin; -} lora_sx1276; - - -// LORA Module setup // - -// Initialize LORA with default parameters: -// Params: -// - `lora` LoRa definition to be initialized -// - `spi` SPI HAL bus (`hspi1`, `hspi2`, etc) -// - `nss_port` - GPIO port where `NSS` pin connected to -// - `nss_pin` - GPIO pin number in `nss_port` -// - `freq` - operating frequency. In Hz -// Returns: -// - `LORA_OK` - modem initialized successfully -// - `LORA_ERROR` - initialization failed (e.g. no modem present on SPI bus / wrong NSS port/pin) -uint8_t lora_init(lora_sx1276 *lora, SPI_HandleTypeDef *spi, GPIO_TypeDef *nss_port, - uint16_t nss_pin, uint64_t freq); - -// Returns LoRa modem version number (usually 0x12) -uint8_t lora_version(lora_sx1276 *lora); - - -// LORA mode selection // - -// Put radio into SLEEP mode: -// In this mode only SPI and configuration registers are accessible. -// LoRa FIFO is not accessible. -void lora_mode_sleep(lora_sx1276 *lora); - -// Put radio into standby (idle) mode: -// Both Crystal Oscillator and LoRa baseband blocks are turned on. -// RF part and PLLs are disabled. -void lora_mode_standby(lora_sx1276 *lora); - -// Put radio into continuous receive mode: -// When activated the RFM95/96/97/98(W) powers all remaining blocks required for reception, -// processing all received data until a new user request is made to change operating mode. -void lora_mode_receive_continuous(lora_sx1276 *lora); - -// Put radio into single receive mode: -// When activated the RFM95/96/97/98(W) powers all remaining blocks required for reception, remains in -// this state until a valid packet has been received and then returns to Standby mode. -void lora_mode_receive_single(lora_sx1276 *lora); - - -// LORA signal / transmission parameters // - -// Sets LoRa transmit power. -// Params: -// - `level` - TX power in dBm. Valid range from 2dBm to 20dBm -void lora_set_tx_power(lora_sx1276 *lora, uint8_t level); - -// Set operational frequency. -// Params: -// - `freq` - frequency in Hz -void lora_set_frequency(lora_sx1276 *lora, uint64_t freq); - -// Set signal bandwidth. -// Params: -// - `bw` - desired bandwidth, from LORA_BANDWIDTH_7_8_KHZ to LORA_BANDWIDTH_500_KHZ -// For more information refer to section 4.1 of datasheet. -void lora_set_signal_bandwidth(lora_sx1276 *lora, uint64_t bw); - -// Set signal spreading factor. -// Params: -// - `sf` - spreading factor. Value from 6 to 12 -// For more information refer to section 4.1 of datasheet. -void lora_set_spreading_factor(lora_sx1276 *lora, uint8_t sf); - -// Set coding rate. -// - `rate` - coding rate. Use any of LORA_CODING_RATE* constants. -// For more information refer to section 4.1 of datasheet. -void lora_set_coding_rate(lora_sx1276 *lora, uint8_t rate); - -// Enable / disable CRC -// Params: -// - `enable` - set to 0 to disable CRC, any other value enables CRC. -void lora_set_crc(lora_sx1276 *lora, uint8_t enable); - -// Set length of packet preamble. -// Params: -// - `len` - length of packet preamble -// For more information refer to section 4.1.1.6 of datasheet -void lora_set_preamble_length(lora_sx1276 *lora, uint16_t len); - -// Set "implicit header" mode, meaning no packet header at all. -// Refer to section 4.1.1.6 of datasheet -void lora_set_implicit_header_mode(lora_sx1276 *lora); - -// Set "explicit", i.e. always add packet header with various system information. -// Refer to section 4.1.1.6 of datasheet -void lora_set_explicit_header_mode(lora_sx1276 *lora); - - -// Received packet information // - -// Returns RSSI of last received packet -int8_t lora_packet_rssi(lora_sx1276 *lora); - -// Returns SNR of last received packet -uint8_t lora_packet_snr(lora_sx1276 *lora); - - -// SEND packet routines // - -// Query modem for any ongoing packet transmission. -// Returns 0 if no active transmission present -uint8_t lora_is_transmitting(lora_sx1276 *lora); - -// Send packet in non-blocking mode -// Params: -// - `data` - pointer to buffer to be transmitted -// - `data_len` - how many bytes to transmit from `data` buffer. -// Returns: -// - `LORA_BUSY` in case of active transmission ongoing -// - `LORA_OK` packet scheduled to be sent. -// Check state with `lora_is_transmitting()` or by interrupt. -uint8_t lora_send_packet(lora_sx1276 *lora, uint8_t *data, uint8_t data_len); - -// Send packet using DMA mode. -// You must call lora_send_packet_dma_complete() from DMA transfer complete callback -// Params: -// - `data` - pointer to buffer to be transmitted -// - `data_len` - how many bytes to transmit from `data` buffer. -// Returns: -// - `LORA_BUSY` in case of active transmission ongoing -// - `LORA_TIMEOUT` packet wasn't transmitted in given time frame. -// - `LORA_OK` packet scheduled to be sent. -uint8_t lora_send_packet_dma_start(lora_sx1276 *lora, uint8_t *data, uint8_t data_len); - -// Finish packet send initiated by lora_send_packet_dma_start() -void lora_send_packet_dma_complete(lora_sx1276 *lora); - -// Send packet and returns only when packet sent / error occurred (blocking mode). -// Params: -// - `data` - pointer to buffer to be transmitted -// - `data_len` - how many bytes to transmit from `data` buffer. -// - `timeout` - maximum wait time to finish transmission. -// Returns: -// - `LORA_BUSY` in case of active transmission ongoing -// - `LORA_TIMEOUT` packet wasn't transmitted in given time frame. -// - `LORA_OK` packet scheduled to be sent. -uint8_t lora_send_packet_blocking(lora_sx1276 *lora, uint8_t *data, uint8_t data_len, uint32_t timeout); - - -// RECEIVE packet routines // - -// Checks if packet modem has packet awaiting to be received -// Returns 0 if no packet is available, or any positive integer in case packet is ready -uint8_t lora_is_packet_available(lora_sx1276 *lora); - -// If modem has packet awaiting to be received - returns it's length. -uint8_t lora_pending_packet_length(lora_sx1276 *lora); - -// Receives packet from LoRa modem -// Params: -// - `buffer` - pointer to buffer where copy packet to. -// - `buffer_len` - length of `buffer`. If incoming packet greater than `buffer_len` it will be truncated -// to fit `buffer_len`. -// - `error` - pointer to `uint8_t` to store error. Can be NULL - so no error information will be stored. -// Returns actual packet length stored into `buffer`. -// -// `error` is one of: -// - `LORA_OK` - packet successfully received. -// - `LORA_EMPTY` - no packet received at the moment (check for packet by `lora_is_packet_available()` before). -// - `LORA_TIMEOUT` - timeout while receiving packet (only for single receive mode). -// - `LORA_INVALID_HEADER` - packet with malformed header received. -// - `LORA_CRC_ERROR` - malformed packet received (CRC failed). Please note that you need to enable -// this functionality explicitly, it is disabled by default. -uint8_t lora_receive_packet(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, uint8_t *error); - -// Start receiving packet from LoRa modem in DMA mode. -// 1. In case of single receive mode: when packet arrived or timeout occurred. -// Please note that it is not enough to set `timeout` to something positive - -// you also need to set timeout in LoRa modem by calling `lora_set_rx_symbol_timeout` before. -// 2. For continuous receiving mode will wait until packet arrived / timeout occurred. -// Params: -// - `buffer` - pointer to buffer where copy packet to. -// - `buffer_len` - length of `buffer`. If incoming packet greater than `buffer_len` it will be truncated -// to fit `buffer_len`. -// - `error` - pointer to `uint8_t` to store error. Can be NULL - so no error information will be stored. -// Returns actual packet length stored into `buffer`. -// -// `error` is one of: -// - `LORA_OK` - packet successfully received. -// - `LORA_EMPTY` - no packet received at the moment (check for packet by `lora_is_packet_available()` before). -// - `LORA_TIMEOUT` - timeout while receiving packet (only for single receive mode). -// - `LORA_INVALID_HEADER` - packet with malformed header received. -// - `LORA_CRC_ERROR` - malformed packet received (CRC failed). Please note that you need to enable -// this functionality explicitly, it is disabled by default. -uint8_t lora_receive_packet_dma_start(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, - uint8_t *error); - -// Finish receive packet in DMA dome -void lora_receive_packet_dma_complete(lora_sx1276 *lora); - - -// Receive packet in "blocking mode" i.e. function return only when packet: -// 1. In case of single receive mode: when packet arrived or timeout occurred. -// Please note that it is not enough to set `timeout` to something positive - -// you also need to set timeout in LoRa modem by calling `lora_set_rx_symbol_timeout` before. -// 2. For continuous receiving mode will wait until packet arrived / timeout occurred. -// Params: -// - `buffer` - pointer to buffer where copy packet to. -// - `buffer_len` - length of `buffer`. If incoming packet greater than `buffer_len` it will be truncated -// to fit `buffer_len`. -// - `error` - pointer to `uint8_t` to store error. Can be NULL - so no error information will be stored. -// Returns actual packet length stored into `buffer`. -// -// `error` is one of: -// - `LORA_OK` - packet successfully received. -// - `LORA_EMPTY` - no packet received at the moment (check for packet by `lora_is_packet_available()` before). -// - `LORA_TIMEOUT` - timeout while receiving packet (only for single receive mode). -// - `LORA_INVALID_HEADER` - packet with malformed header received. -// - `LORA_CRC_ERROR` - malformed packet received (CRC failed). Please note that you need to enable -// this functionality explicitly, it is disabled by default. -uint8_t lora_receive_packet_blocking(lora_sx1276 *lora, uint8_t *buffer, uint8_t buffer_len, - uint32_t timeout, uint8_t *error); - -// Sets timeout for `lora_mode_receive_single()` in symbols. -// Params: -// - `symbols` - timeout value. Valid from `4` to `1024` symbols. -// For more information refer to datasheet section 4.1.5 -void lora_set_rx_symbol_timeout(lora_sx1276 *lora, uint16_t symbols); - - -// Enables interrupt on DIO0 when packet received -// SX1276 module will pull DIO0 line high -void lora_enable_interrupt_rx_done(lora_sx1276 *lora); - -// Enables interrupt on DIO0 when transmission is done -// SX1276 module will pull DIO0 line high -void lora_enable_interrupt_tx_done(lora_sx1276 *lora); - -// Clears all RX interrupts on DIO0 (done, timeout, crc, etc) -void lora_clear_interrupt_rx_all(lora_sx1276 *lora); - -// Clears TX interrupt on DIO0 -void lora_clear_interrupt_tx_done(lora_sx1276 *lora); - -#endif From 8eaaae19950ee139b5ab3344b02d5f9b15b5124f Mon Sep 17 00:00:00 2001 From: niekky Date: Thu, 16 Jan 2025 12:41:17 -0700 Subject: [PATCH 27/60] Refactored code --- lora/lora.c | 65 ++++++++++++++++++++++++++++------------------------- lora/lora.h | 15 ++++++------- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 511fd1a..c8eff7f 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -31,58 +31,45 @@ /*------------------------------------------------------------------------------ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ -//TODO: Switch pinState to a good enum -void lora_write_cs_pin( CS_STATUS pinState ) { - /* Takes either GPIO_PIN_SET or GPIO_PIN_RESET to bring the chip select pin - high or low. I use the HAL enums because that's what our flash module - does as well. */ - if( pinState == CS_HIGH ) { - HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); - } else { - HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - } -} - -LORA_STATUS lora_spi_receive( uint8_t* read_buffer_ptr ) { +LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ) { HAL_StatusTypeDef status; /* Takes pointer to the read buffer. and puts output there */ status = HAL_SPI_Receive( &(hspi4), &read_buffer_ptr[0], 2, HAL_DEFAULT_TIMEOUT ); - if (status == LORA_OK){ + if (status == HAL_OK){ return LORA_OK; } else return LORA_FAIL; } -LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { +LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { HAL_StatusTypeDef status; /* Takes register and data to write (1 byte) and writes that register. */ uint8_t transmitBuffer[2] = { reg, data }; status = HAL_SPI_Transmit( &(hspi4), &transmitBuffer[0], 2, HAL_DEFAULT_TIMEOUT); - if (status == LORA_OK){ + if (status == HAL_OK){ return LORA_OK; } else return LORA_FAIL; } -LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData) { +LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData) { LORA_STATUS transmit_status, receive_status; - lora_write_cs_pin( CS_LOW ); + HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - transmit_status = lora_spi_transmit( (lora_register | 0b00000000), 0b00000000 ); // The problem starts here - transmit_status = LORA_OK; - receive_status = lora_spi_receive( ®Data[0] ); + transmit_status = LORA_SPI_Transmit( (lora_register | 0b00000000), 0b00000000 ); // The problem starts here + receive_status = LORA_SPI_Receive( ®Data[0] ); - lora_write_cs_pin( CS_HIGH ); + HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); // I've temporarily added RECEIVE_FAIL and TRANSMIT_FAIL to the enum to be able to pinpoint issues // This will be removed in the final code, and this function will only be able to output // LORA_OK or LORA_FAIL - if (transmit_status | receive_status == 0){ + if (transmit_status + receive_status == 0){ return LORA_OK; } else if( transmit_status == LORA_FAIL ) { return LORA_TRANSMIT_FAIL; @@ -94,8 +81,29 @@ LORA_STATUS lora_spi_get_register( LORA_REGISTER_ADDR lora_register, uint8_t* re } -LORA_STATUS lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { - return lora_spi_transmit( (lora_register | 0b10000000), data ); +LORA_STATUS lora_write_register( LORA_REGISTER_ADDR lora_register, uint8_t data ) { + LORA_STATUS status; + + HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); + + status = LORA_SPI_Transmit( (lora_register | 0b10000000), data ); + + HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); + + if ( status == LORA_OK ) + return LORA_OK; + else return LORA_FAIL; +} + +// Get the device chip ID +LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr) { + LORA_STATUS status; + + status = lora_read_register( LORA_REG_ID_VERSION, &buffer_ptr[0] ); + + if ( status == LORA_OK ) + return LORA_OK; + else return LORA_FAIL; } /*------------------------------------------------------------------------------ @@ -131,9 +139,4 @@ LORA_STATUS lora_spi_set_register( LORA_REGISTER_ADDR lora_register, uint8_t dat // // Bring chip select back high // lora_write_cs_pin( GPIO_PIN_RESET ); -// } - -// Get the device chip ID -LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr) { - return lora_spi_get_register( LORA_REG_ID_VERSION, &buffer_ptr[0]); -} \ No newline at end of file +// } \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index 4f6c19b..34db405 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -45,11 +45,6 @@ typedef enum LORA_STATUS { LORA_RECEIVE_FAIL } LORA_STATUS; -typedef enum _CS_STATUS { - CS_LOW = 0, - CS_HIGH -} CS_STATUS; - /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) Note: as we are using LoRa, the FSK opcodes are not included*/ typedef enum LORA_REGISTER_ADDR { @@ -100,10 +95,14 @@ typedef enum LORA_REGISTER_ADDR { LORA_REG_AGC_THRESHOLD_4 = 0x64 } LORA_REGISTER_ADDR; -LORA_STATUS lora_spi_receive( uint8_t read_buffer[] ); +LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); + +LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ); + +LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData); -LORA_STATUS lora_spi_transmit( LORA_REGISTER_ADDR register, uint8_t data ); +LORA_STATUS lora_write_register( LORA_REGISTER_ADDR lora_register, uint8_t data ); -LORA_STATUS lora_get_device_id(uint8_t* packet); +LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr); #endif \ No newline at end of file From a84c61b3db39fcf08f071660bb72538dbb213aa5 Mon Sep 17 00:00:00 2001 From: niekky Date: Thu, 16 Jan 2025 13:02:57 -0700 Subject: [PATCH 28/60] Fixed bitwise r/w filter --- lora/lora.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index c8eff7f..c146e93 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -61,7 +61,7 @@ LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regDa HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - transmit_status = LORA_SPI_Transmit( (lora_register | 0b00000000), 0b00000000 ); // The problem starts here + transmit_status = LORA_SPI_Transmit( (lora_register & 0x7F), 0x00 ); // The problem starts here receive_status = LORA_SPI_Receive( ®Data[0] ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); @@ -86,7 +86,7 @@ LORA_STATUS lora_write_register( LORA_REGISTER_ADDR lora_register, uint8_t data HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - status = LORA_SPI_Transmit( (lora_register | 0b10000000), data ); + status = LORA_SPI_Transmit( (lora_register | 0x80), data ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); From 34a654de880d9b7e7c3008614bdb3bbc0451df4b Mon Sep 17 00:00:00 2001 From: niekky Date: Mon, 20 Jan 2025 18:10:24 -0700 Subject: [PATCH 29/60] Debugging SPI4 --- lora/lora.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index c146e93..3441b37 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -35,7 +35,7 @@ LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ) { HAL_StatusTypeDef status; /* Takes pointer to the read buffer. and puts output there */ - status = HAL_SPI_Receive( &(hspi4), &read_buffer_ptr[0], 2, HAL_DEFAULT_TIMEOUT ); + status = HAL_SPI_Receive( &(FLASH_LORA), &read_buffer_ptr[0], 2, 2000 ); if (status == HAL_OK){ return LORA_OK; @@ -48,7 +48,8 @@ LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { /* Takes register and data to write (1 byte) and writes that register. */ uint8_t transmitBuffer[2] = { reg, data }; - status = HAL_SPI_Transmit( &(hspi4), &transmitBuffer[0], 2, HAL_DEFAULT_TIMEOUT); + // uint8_t transmitBuffer = reg; + status = HAL_SPI_Transmit( &(FLASH_LORA), &transmitBuffer, 2, 2000); if (status == HAL_OK){ return LORA_OK; @@ -71,10 +72,6 @@ LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regDa // LORA_OK or LORA_FAIL if (transmit_status + receive_status == 0){ return LORA_OK; - } else if( transmit_status == LORA_FAIL ) { - return LORA_TRANSMIT_FAIL; - } else if( receive_status == LORA_RECEIVE_FAIL ) { - return LORA_RECEIVE_FAIL; } else { return LORA_FAIL; } From d3ba37867f6f84cf9791eca2826f4169bc73c2f3 Mon Sep 17 00:00:00 2001 From: niekky Date: Thu, 23 Jan 2025 08:40:11 -0700 Subject: [PATCH 30/60] Fixed typo --- lora/lora.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 3441b37..82306af 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -35,7 +35,7 @@ LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ) { HAL_StatusTypeDef status; /* Takes pointer to the read buffer. and puts output there */ - status = HAL_SPI_Receive( &(FLASH_LORA), &read_buffer_ptr[0], 2, 2000 ); + status = HAL_SPI_Receive( &(LORA_SPI), &read_buffer_ptr[0], 2, 2000 ); if (status == HAL_OK){ return LORA_OK; @@ -49,7 +49,7 @@ LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { /* Takes register and data to write (1 byte) and writes that register. */ uint8_t transmitBuffer[2] = { reg, data }; // uint8_t transmitBuffer = reg; - status = HAL_SPI_Transmit( &(FLASH_LORA), &transmitBuffer, 2, 2000); + status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer[0], 2, 2000); if (status == HAL_OK){ return LORA_OK; @@ -67,9 +67,6 @@ LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regDa HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); - // I've temporarily added RECEIVE_FAIL and TRANSMIT_FAIL to the enum to be able to pinpoint issues - // This will be removed in the final code, and this function will only be able to output - // LORA_OK or LORA_FAIL if (transmit_status + receive_status == 0){ return LORA_OK; } else { From 845f83c1f060536c1bc3aa40b95f816395f32a7a Mon Sep 17 00:00:00 2001 From: niekky Date: Thu, 23 Jan 2025 16:51:57 -0700 Subject: [PATCH 31/60] Working Lora --- lora/lora.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 82306af..d02d47d 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -35,7 +35,7 @@ LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ) { HAL_StatusTypeDef status; /* Takes pointer to the read buffer. and puts output there */ - status = HAL_SPI_Receive( &(LORA_SPI), &read_buffer_ptr[0], 2, 2000 ); + status = HAL_SPI_Receive( &(LORA_SPI), read_buffer_ptr, 1, 2000 ); if (status == HAL_OK){ return LORA_OK; @@ -47,9 +47,9 @@ LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { HAL_StatusTypeDef status; /* Takes register and data to write (1 byte) and writes that register. */ - uint8_t transmitBuffer[2] = { reg, data }; - // uint8_t transmitBuffer = reg; - status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer[0], 2, 2000); + // uint8_t transmitBuffer[2] = { reg, data }; + uint8_t transmitBuffer = reg; + status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, 2000); if (status == HAL_OK){ return LORA_OK; @@ -57,13 +57,13 @@ LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { } -LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData) { +LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* pRegData) { LORA_STATUS transmit_status, receive_status; HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); transmit_status = LORA_SPI_Transmit( (lora_register & 0x7F), 0x00 ); // The problem starts here - receive_status = LORA_SPI_Receive( ®Data[0] ); + receive_status = LORA_SPI_Receive( pRegData ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); @@ -93,7 +93,7 @@ LORA_STATUS lora_write_register( LORA_REGISTER_ADDR lora_register, uint8_t data LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr) { LORA_STATUS status; - status = lora_read_register( LORA_REG_ID_VERSION, &buffer_ptr[0] ); + status = lora_read_register( LORA_REG_ID_VERSION, buffer_ptr ); if ( status == LORA_OK ) return LORA_OK; From 60d0fb9654a020c6024a04fb5270afd178c42e38 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Thu, 23 Jan 2025 18:31:10 -0700 Subject: [PATCH 32/60] Split LoRa SPI transmit into single and double variants --- lora/lora.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index d02d47d..dad3727 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -43,7 +43,7 @@ LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ) { return LORA_FAIL; } -LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { +LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg ) { HAL_StatusTypeDef status; /* Takes register and data to write (1 byte) and writes that register. */ @@ -56,13 +56,24 @@ LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ) { } else return LORA_FAIL; } +LORA_STATUS LORA_SPI_Transmit_Double( LORA_REGISTER_ADDR reg, uint8_t data ) { + HAL_StatusTypeDef status; + + /* Takes register and data to write (1 byte) and writes that register. */ + uint8_t transmitBuffer[2] = { reg, data }; + status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, 2000); + + if (status == HAL_OK){ + return LORA_OK; + } else return LORA_FAIL; +} LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* pRegData) { LORA_STATUS transmit_status, receive_status; HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - transmit_status = LORA_SPI_Transmit( (lora_register & 0x7F), 0x00 ); // The problem starts here + transmit_status = LORA_SPI_Transmit_Single( (lora_register & 0x7F), 0x00 ); // The problem starts here receive_status = LORA_SPI_Receive( pRegData ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); @@ -80,7 +91,7 @@ LORA_STATUS lora_write_register( LORA_REGISTER_ADDR lora_register, uint8_t data HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - status = LORA_SPI_Transmit( (lora_register | 0x80), data ); + status = LORA_SPI_Transmit_Double( (lora_register | 0x80), data ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); From e6391396eca898e5db62b96d37f228f9ec10bc10 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Mon, 27 Jan 2025 19:14:27 -0700 Subject: [PATCH 33/60] Add LoRa transmit support --- lora/lora.c | 2 +- lora/lora.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index dad3727..bd49c47 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -73,7 +73,7 @@ LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* pRegD HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - transmit_status = LORA_SPI_Transmit_Single( (lora_register & 0x7F), 0x00 ); // The problem starts here + transmit_status = LORA_SPI_Transmit_Single( (lora_register & 0x7F) ); receive_status = LORA_SPI_Receive( pRegData ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); diff --git a/lora/lora.h b/lora/lora.h index 34db405..f712de6 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -97,7 +97,9 @@ typedef enum LORA_REGISTER_ADDR { LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); -LORA_STATUS LORA_SPI_Transmit( LORA_REGISTER_ADDR reg, uint8_t data ); +LORA_STATUS LORA_SPI_Transmit_Double( LORA_REGISTER_ADDR reg, uint8_t data ); + +LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg, uint8_t data ); LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData); From f69618acd7a330418f2ea25cf444f94a8cfb7ed3 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Mon, 27 Jan 2025 19:14:57 -0700 Subject: [PATCH 34/60] Add LoRa transmit (again. I had to undo stuff to make another branch) --- lora/lora.c | 82 +++++++++++++++++++++++++++++++++-------------------- lora/lora.h | 8 +++++- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index bd49c47..ed82a14 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -114,34 +114,54 @@ LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr) { /*------------------------------------------------------------------------------ Function to set the mode of the chip ------------------------------------------------------------------------------*/ -// void lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { -// /* chip_mode should be one of the following 3-bit variables defined in lora.h -// #define LORA_SLEEP_MODE 0b000 -// #define LORA_STANDBY_MODE 0b001 -// #define LORA_FREQ_SYNTH_TX_MODE 0b010 -// #define LORA_TRANSMIT_MODE 0b011 -// #define LORA_FREQ_SYNTH_RX_MODE 0b100 -// #define LORA_RX_CONTINUOUS_MODE 0b101 -// #define LORA_RX_SINGLE_MODE 0b111 -// */ -// // I may give this function a return type in the future to check success of operation. -// // Also, may need to be updated based on pin definitions after those are fixed. - -// // Pull chip select low -// lora_write_cs_pin( GPIO_PIN_SET ); - -// // Get initial value of the operation mode register -// uint8_t operation_mode_register = lora_spi_get_register( LORA_REG_OPERATION_MODE ); - -// // Shift the chip mode bits to be the first 3 bits of the sequence -// uint8_t shifted_chip_mode = (chip_mode << 0b00000); - -// // Change the value of the chip register to set it to the suggested chip mode -// uint8_t new_opmode_register = (operation_mode_register | chip_mode); - -// // Write new bit -// lora_spi_set_register( LORA_REG_OPERATION_MODE, new_opmode_register );LORA_REG_ - -// // Bring chip select back high -// lora_write_cs_pin( GPIO_PIN_RESET ); -// } \ No newline at end of file +LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { + /* chip_mode should be one of the following 3-bit variables defined in lora.h + #define LORA_SLEEP_MODE 0b000 + #define LORA_STANDBY_MODE 0b001 + #define LORA_FREQ_SYNTH_TX_MODE 0b010 + #define LORA_TRANSMIT_MODE 0b011 + #define LORA_FREQ_SYNTH_RX_MODE 0b100 + #define LORA_RX_CONTINUOUS_MODE 0b101 #define LORA_RX_SINGLE_MODE 0b111 + */ + // I may give this function a return type in the future to check success of operation. + + // Get initial value of the operation mode register + uint8_t operation_mode_register; + LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); + + // Shift the chip mode bits to be the first 3 bits of the sequence + uint8_t shifted_chip_mode = (chip_mode << 0b00000); + + // Change the value of the chip register to set it to the suggested chip mode + uint8_t new_opmode_register = (operation_mode_register | shifted_chip_mode); + + // Write new bit + LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); + + if ( write_status + read_status == 0){ + return LORA_OK; + } else { + return LORA_FAIL; + } +} + +LORA_STATUS lora_init() { + return lora_set_chip_mode( LORA_STANDBY_MODE ); +} + +LORA_STATUS lora_transmit( uint8_t data ) { + LORA_STATUS data_write = lora_write_register( LORA_REG_FIFO_RW, 255 ); + + LORA_STATUS chip_mode_status = lora_set_chip_mode( LORA_TRANSMIT_MODE ); + + uint8_t transmit_status = 0b00000000; // This variable holds the IRQ register, which is checked for transmit done flag + while( ( transmit_status & 0b00010000 ) != 0b00010000 ) { // We use this bitmask to check the 4th bit to see if transmission is done + lora_read_register( LORA_REG_LORA_STATE_FLAGS, &transmit_status ); + } + + if ( data_write + chip_mode_status == 0){ + return LORA_OK; + } else { + return LORA_FAIL; + } +} \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index f712de6..5d8a845 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -99,7 +99,7 @@ LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); LORA_STATUS LORA_SPI_Transmit_Double( LORA_REGISTER_ADDR reg, uint8_t data ); -LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg, uint8_t data ); +LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg ); LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData); @@ -107,4 +107,10 @@ LORA_STATUS lora_write_register( LORA_REGISTER_ADDR lora_register, uint8_t data LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr); +LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ); + +LORA_STATUS lora_init(); + +LORA_STATUS lora_transmit( uint8_t data ); + #endif \ No newline at end of file From 1b65456db35c4a5206b72647d8d2efa01ec538f8 Mon Sep 17 00:00:00 2001 From: Drew Date: Mon, 3 Feb 2025 19:44:11 -0700 Subject: [PATCH 35/60] Make Lora init more functional and add more checks to setchipmode --- lora/lora.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index ed82a14..81aa95d 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -128,6 +128,9 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { // Get initial value of the operation mode register uint8_t operation_mode_register; LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); + if( read_status & 0b00000001 != 0b00000001 ) { // Make function automatically fail if chip is not in LoRa mode + return LORA_FAIL; + } // Shift the chip mode bits to be the first 3 bits of the sequence uint8_t shifted_chip_mode = (chip_mode << 0b00000); @@ -135,7 +138,7 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { // Change the value of the chip register to set it to the suggested chip mode uint8_t new_opmode_register = (operation_mode_register | shifted_chip_mode); - // Write new bit + // Write new byte LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); if ( write_status + read_status == 0){ @@ -146,9 +149,23 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { } LORA_STATUS lora_init() { - return lora_set_chip_mode( LORA_STANDBY_MODE ); -} + LORA_STATUS set_sleep_status = lora_set_chip_mode( LORA_SLEEP_MODE ); // Switch to sleep mode to enable LoRa bit (datasheeet page 102) + // Get initial value of the operation mode register + uint8_t operation_mode_register; + LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); + uint8_t new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit + // Write new byte + LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); + LORA_STATUS standby_status = lora_set_chip_mode( LORA_STANDBY_MODE ); // Switch it into standby mode, which is what's convenient. + + if( set_sleep_status + read_status + write_status + standby_status == 0 ) { + return LORA_OK; + } else { + return LORA_FAIL; + } +} +/* LORA_STATUS lora_transmit( uint8_t data ) { LORA_STATUS data_write = lora_write_register( LORA_REG_FIFO_RW, 255 ); @@ -164,4 +181,5 @@ LORA_STATUS lora_transmit( uint8_t data ) { } else { return LORA_FAIL; } -} \ No newline at end of file +} +*/ \ No newline at end of file From 7d2dd93d61c09f6e0fbdba4592fa16bf37914c97 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 14 Feb 2025 15:02:12 -0700 Subject: [PATCH 36/60] Add LoRa config struct --- lora/lora.c | 16 +++++++++++++--- lora/lora.h | 15 ++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 81aa95d..47f2fc4 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -148,16 +148,19 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { } } -LORA_STATUS lora_init() { +LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { LORA_STATUS set_sleep_status = lora_set_chip_mode( LORA_SLEEP_MODE ); // Switch to sleep mode to enable LoRa bit (datasheeet page 102) // Get initial value of the operation mode register uint8_t operation_mode_register; LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); - uint8_t new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit + uint8_t new_opmode_register; + if( lora_config_ptr->lora_enabled == LORA_ENABLED ) { + new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit + } // Write new byte LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); - LORA_STATUS standby_status = lora_set_chip_mode( LORA_STANDBY_MODE ); // Switch it into standby mode, which is what's convenient. + LORA_STATUS standby_status = lora_set_chip_mode( lora_config_ptr->lora_mode ); // Switch it into standby mode, which is what's convenient. if( set_sleep_status + read_status + write_status + standby_status == 0 ) { return LORA_OK; @@ -165,6 +168,13 @@ LORA_STATUS lora_init() { return LORA_FAIL; } } + +void lora_reset() { + HAL_GPIO_WritePin(LORA_RST_GPIO_PORT, LORA_RST_PIN, GPIO_PIN_RESET); // Pull Low + HAL_Delay(10); // Hold reset low for 10 ms + HAL_GPIO_WritePin(LORA_RST_GPIO_PORT, LORA_RST_PIN, GPIO_PIN_SET); // Pull High + HAL_Delay(10); // Wait for SX1278 to stabilize +} /* LORA_STATUS lora_transmit( uint8_t data ) { LORA_STATUS data_write = lora_write_register( LORA_REG_FIFO_RW, 255 ); diff --git a/lora/lora.h b/lora/lora.h index 5d8a845..099a11c 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -45,6 +45,11 @@ typedef enum LORA_STATUS { LORA_RECEIVE_FAIL } LORA_STATUS; +typedef enum LORA_ENABLE { + LORA_ENABLED, + LORA_DISABLED +} LORA_ENABLE; + /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) Note: as we are using LoRa, the FSK opcodes are not included*/ typedef enum LORA_REGISTER_ADDR { @@ -95,6 +100,12 @@ typedef enum LORA_REGISTER_ADDR { LORA_REG_AGC_THRESHOLD_4 = 0x64 } LORA_REGISTER_ADDR; +/* LORA CONFIG SETTINGS */ +typedef struct _LORA_CONFIG { + LORA_ENABLE lora_enabled; // LORA enablement status + LORA_CHIPMODE lora_mode; // Current LORA Chipmode +} LORA_CONFIG; + LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); LORA_STATUS LORA_SPI_Transmit_Double( LORA_REGISTER_ADDR reg, uint8_t data ); @@ -111,6 +122,8 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ); LORA_STATUS lora_init(); -LORA_STATUS lora_transmit( uint8_t data ); +void lora_reset(); + +// LORA_STATUS lora_transmit( uint8_t data ); #endif \ No newline at end of file From 1392fe00e5293a7cf6c4cd83ddaf8c234c0a9b98 Mon Sep 17 00:00:00 2001 From: niekky Date: Mon, 17 Feb 2025 18:12:21 -0700 Subject: [PATCH 37/60] Replaced 2000 with LORA_TIMEOUT macro --- lora/lora.c | 6 +++--- lora/lora.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 47f2fc4..570654c 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -35,7 +35,7 @@ LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ) { HAL_StatusTypeDef status; /* Takes pointer to the read buffer. and puts output there */ - status = HAL_SPI_Receive( &(LORA_SPI), read_buffer_ptr, 1, 2000 ); + status = HAL_SPI_Receive( &(LORA_SPI), read_buffer_ptr, 1, LORA_TIMEOUT ); if (status == HAL_OK){ return LORA_OK; @@ -49,7 +49,7 @@ LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg ) { /* Takes register and data to write (1 byte) and writes that register. */ // uint8_t transmitBuffer[2] = { reg, data }; uint8_t transmitBuffer = reg; - status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, 2000); + status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, LORA_TIMEOUT); if (status == HAL_OK){ return LORA_OK; @@ -61,7 +61,7 @@ LORA_STATUS LORA_SPI_Transmit_Double( LORA_REGISTER_ADDR reg, uint8_t data ) { /* Takes register and data to write (1 byte) and writes that register. */ uint8_t transmitBuffer[2] = { reg, data }; - status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, 2000); + status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, LORA_TIMEOUT); if (status == HAL_OK){ return LORA_OK; diff --git a/lora/lora.h b/lora/lora.h index 099a11c..4fa9fb9 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -27,6 +27,8 @@ they are commented out for now and will be uncommented as they're needed. #define LORA_OPERATION_RESERVED 0b00 */ +#define LORA_TIMEOUT 2000 + typedef enum LORA_CHIPMODE { LORA_SLEEP_MODE = 0b000, LORA_STANDBY_MODE = 0b001, From b52f217d51f8f571a53bec18f69f8b6e1e864f91 Mon Sep 17 00:00:00 2001 From: niekky Date: Mon, 17 Feb 2025 18:17:40 -0700 Subject: [PATCH 38/60] Followed name convention --- lora/lora.c | 11 +++++------ lora/lora.h | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 570654c..9e65fe8 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -43,11 +43,10 @@ LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ) { return LORA_FAIL; } -LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg ) { +LORA_STATUS LORA_SPI_Transmit_Byte( LORA_REGISTER_ADDR reg ) { HAL_StatusTypeDef status; /* Takes register and data to write (1 byte) and writes that register. */ - // uint8_t transmitBuffer[2] = { reg, data }; uint8_t transmitBuffer = reg; status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, LORA_TIMEOUT); @@ -56,10 +55,10 @@ LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg ) { } else return LORA_FAIL; } -LORA_STATUS LORA_SPI_Transmit_Double( LORA_REGISTER_ADDR reg, uint8_t data ) { +LORA_STATUS LORA_SPI_Transmit_Data( LORA_REGISTER_ADDR reg, uint8_t data ) { HAL_StatusTypeDef status; - /* Takes register and data to write (1 byte) and writes that register. */ + /* Takes register and data to write and writes that register. */ uint8_t transmitBuffer[2] = { reg, data }; status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, LORA_TIMEOUT); @@ -73,7 +72,7 @@ LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* pRegD HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - transmit_status = LORA_SPI_Transmit_Single( (lora_register & 0x7F) ); + transmit_status = LORA_SPI_Transmit_Byte( (lora_register & 0x7F) ); receive_status = LORA_SPI_Receive( pRegData ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); @@ -91,7 +90,7 @@ LORA_STATUS lora_write_register( LORA_REGISTER_ADDR lora_register, uint8_t data HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_RESET ); - status = LORA_SPI_Transmit_Double( (lora_register | 0x80), data ); + status = LORA_SPI_Transmit_Data( (lora_register | 0x80), data ); HAL_GPIO_WritePin( LORA_NSS_GPIO_PORT, LORA_NSS_PIN, GPIO_PIN_SET ); diff --git a/lora/lora.h b/lora/lora.h index 4fa9fb9..37ecbe7 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -110,9 +110,9 @@ typedef struct _LORA_CONFIG { LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); -LORA_STATUS LORA_SPI_Transmit_Double( LORA_REGISTER_ADDR reg, uint8_t data ); +LORA_STATUS LORA_SPI_Transmit_Buffer( LORA_REGISTER_ADDR reg, uint8_t data ); -LORA_STATUS LORA_SPI_Transmit_Single( LORA_REGISTER_ADDR reg ); +LORA_STATUS LORA_SPI_Transmit_Byte( LORA_REGISTER_ADDR reg ); LORA_STATUS lora_read_register( LORA_REGISTER_ADDR lora_register, uint8_t* regData); From 7cb1ae8b76314691699a1ccbadc617bcde6ae9fd Mon Sep 17 00:00:00 2001 From: niekky Date: Mon, 17 Feb 2025 19:16:49 -0700 Subject: [PATCH 39/60] code reviewed --- lora/lora.c | 22 ++++++++++------------ lora/lora.h | 15 ++++++++------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 9e65fe8..f200795 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -114,23 +114,21 @@ LORA_STATUS lora_get_device_id(uint8_t* buffer_ptr) { Function to set the mode of the chip ------------------------------------------------------------------------------*/ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { - /* chip_mode should be one of the following 3-bit variables defined in lora.h - #define LORA_SLEEP_MODE 0b000 - #define LORA_STANDBY_MODE 0b001 - #define LORA_FREQ_SYNTH_TX_MODE 0b010 - #define LORA_TRANSMIT_MODE 0b011 - #define LORA_FREQ_SYNTH_RX_MODE 0b100 - #define LORA_RX_CONTINUOUS_MODE 0b101 #define LORA_RX_SINGLE_MODE 0b111 - */ - // I may give this function a return type in the future to check success of operation. - // Get initial value of the operation mode register uint8_t operation_mode_register; LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); - if( read_status & 0b00000001 != 0b00000001 ) { // Make function automatically fail if chip is not in LoRa mode - return LORA_FAIL; + // if( read_status & 0b00000001 != 0b00000001 ) { // Make function automatically fail if chip is not in LoRa mode + // return LORA_FAIL; + // } + + if (read_status != LORA_OK) + { + // Error handler } + if !( operation_mode_register & (1<<7) ){ + return LORA_FAIL; + } // Shift the chip mode bits to be the first 3 bits of the sequence uint8_t shifted_chip_mode = (chip_mode << 0b00000); diff --git a/lora/lora.h b/lora/lora.h index 37ecbe7..4d1a2cc 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -30,13 +30,14 @@ they are commented out for now and will be uncommented as they're needed. #define LORA_TIMEOUT 2000 typedef enum LORA_CHIPMODE { - LORA_SLEEP_MODE = 0b000, - LORA_STANDBY_MODE = 0b001, - LORA_FREQ_SYNTH_TX_MODE = 0b010, - LORA_TRANSMIT_MODE = 0b011, - LORA_FREQ_SYNTH_RX_MODE = 0b100, - LORA_RX_CONTINUOUS_MODE = 0b101, - LORA_RX_SINGLE_MODE = 0b111, + LORA_SLEEP_MODE = 0x00, + LORA_STANDBY_MODE = 0x01, + LORA_FREQ_SYNTH_TX_MODE = 0x02, + LORA_TRANSMIT_MODE = 0x03, + LORA_FREQ_SYNTH_RX_MODE = 0x04, + LORA_RX_CONTINUOUS_MODE = 0x05, + LORA_RX_SINGLE_MODE = 0x06, + LORA_RX_CAD = 0x07 } LORA_CHIPMODE; typedef enum LORA_STATUS { From b37a789cc91f1dac3ba5e947214433ea3059315f Mon Sep 17 00:00:00 2001 From: niekky Date: Fri, 21 Feb 2025 11:49:41 -0700 Subject: [PATCH 40/60] Reviewed --- lora/lora.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index f200795..8987693 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -129,11 +129,9 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { if !( operation_mode_register & (1<<7) ){ return LORA_FAIL; } - // Shift the chip mode bits to be the first 3 bits of the sequence - uint8_t shifted_chip_mode = (chip_mode << 0b00000); // Change the value of the chip register to set it to the suggested chip mode - uint8_t new_opmode_register = (operation_mode_register | shifted_chip_mode); + uint8_t new_opmode_register = (operation_mode_register | chip_mode); // Write new byte LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); @@ -151,9 +149,11 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { uint8_t operation_mode_register; LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); uint8_t new_opmode_register; + if( lora_config_ptr->lora_enabled == LORA_ENABLED ) { new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit } + // Write new byte LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); From 0d04a09ccb50a9a4bb5b2869acfccb851b96e269 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 21 Feb 2025 13:04:59 -0700 Subject: [PATCH 41/60] Add spread config --- lora/lora.c | 22 ++++++++++++++-------- lora/lora.h | 18 ++++++++++++------ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 8987693..01789b6 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -123,10 +123,10 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { if (read_status != LORA_OK) { - // Error handler + return LORA_FAIL; } - if !( operation_mode_register & (1<<7) ){ + if ( !( operation_mode_register & (1<<7) ) ){ return LORA_FAIL; } @@ -147,19 +147,25 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { LORA_STATUS set_sleep_status = lora_set_chip_mode( LORA_SLEEP_MODE ); // Switch to sleep mode to enable LoRa bit (datasheeet page 102) // Get initial value of the operation mode register uint8_t operation_mode_register; - LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); + LORA_STATUS read_status1 = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); uint8_t new_opmode_register; - if( lora_config_ptr->lora_enabled == LORA_ENABLED ) { - new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit - } + new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit // Write new byte - LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); + LORA_STATUS write_status1 = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); + + + uint8_t modem_config2_register; + LORA_STATUS read_status2 = lora_read_register( LORA_REG_RX_HEADER_INFO, &modem_config2_register ); + + uint8_t new_config2_register = modem_config2_register & 0x0F; // Erase spread factor bits + uint8_t new_config2_register = ( modem_config2_register | ( lora_config_ptr->lora_spread << 4 ) ); // Set the spread factor + LORA_STATUS write_status2 = lora_write_register( LORA_REG_RX_HEADER_INFO, new_config2_register ); // Write new spread factor LORA_STATUS standby_status = lora_set_chip_mode( lora_config_ptr->lora_mode ); // Switch it into standby mode, which is what's convenient. - if( set_sleep_status + read_status + write_status + standby_status == 0 ) { + if( set_sleep_status + read_status1 + read_status2 + write_status1 + write_status2 + standby_status == 0 ) { return LORA_OK; } else { return LORA_FAIL; diff --git a/lora/lora.h b/lora/lora.h index 4d1a2cc..69b1168 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -48,11 +48,6 @@ typedef enum LORA_STATUS { LORA_RECEIVE_FAIL } LORA_STATUS; -typedef enum LORA_ENABLE { - LORA_ENABLED, - LORA_DISABLED -} LORA_ENABLE; - /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) Note: as we are using LoRa, the FSK opcodes are not included*/ typedef enum LORA_REGISTER_ADDR { @@ -103,10 +98,21 @@ typedef enum LORA_REGISTER_ADDR { LORA_REG_AGC_THRESHOLD_4 = 0x64 } LORA_REGISTER_ADDR; +/* Datasheet page 107 */ +typedef enum LORA_SPREADING_FACTOR { + LORA_SPREAD_6 = 6, + LORA_SPREAD_7 = 7, + LORA_SPREAD_8 = 8, + LORA_SPREAD_9 = 9, + LORA_SPREAD_10 = 10, + LORA_SPREAD_11 = 11, + LORA_SPREAD_12 = 12 +} LORA_SPREADING_FACTOR; + /* LORA CONFIG SETTINGS */ typedef struct _LORA_CONFIG { - LORA_ENABLE lora_enabled; // LORA enablement status LORA_CHIPMODE lora_mode; // Current LORA Chipmode + LORA_SPREADING_FACTOR lora_spread; // LoRa Spread factor } LORA_CONFIG; LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); From d7064ccbb3ad7eac11bb035007a11a46671d1797 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 21 Feb 2025 15:04:34 -0700 Subject: [PATCH 42/60] Add bandwidth and error coding configuation --- lora/lora.c | 16 ++++++++++++---- lora/lora.h | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 01789b6..f8cb34e 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -148,24 +148,32 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { // Get initial value of the operation mode register uint8_t operation_mode_register; LORA_STATUS read_status1 = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); - uint8_t new_opmode_register; + uint8_t new_opmode_register; new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit // Write new byte LORA_STATUS write_status1 = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); - + // Get initial value of config register 2 uint8_t modem_config2_register; LORA_STATUS read_status2 = lora_read_register( LORA_REG_RX_HEADER_INFO, &modem_config2_register ); uint8_t new_config2_register = modem_config2_register & 0x0F; // Erase spread factor bits - uint8_t new_config2_register = ( modem_config2_register | ( lora_config_ptr->lora_spread << 4 ) ); // Set the spread factor + new_config2_register = ( modem_config2_register | ( lora_config_ptr->lora_spread << 4 ) ); // Set the spread factor LORA_STATUS write_status2 = lora_write_register( LORA_REG_RX_HEADER_INFO, new_config2_register ); // Write new spread factor + // Get initial value of config register 1 + uint8_t modem_config1_register; + LORA_STATUS read_status3 = lora_read_register( LORA_REG_NUM_RX_BYTES, &modem_config1_register ); + uint8_t new_config1_register = ( (lora_config_ptr->lora_bandwidth << 4) | (lora_config_ptr->lora_ecr << 1) | ( 0x01 & modem_config1_register ) ); //TODO: Check datasheet for that last bit + + // Write new config1 register + LORA_STATUS write_status3 = lora_write_register( LORA_REG_NUM_RX_BYTES, new_config1_register ); + LORA_STATUS standby_status = lora_set_chip_mode( lora_config_ptr->lora_mode ); // Switch it into standby mode, which is what's convenient. - if( set_sleep_status + read_status1 + read_status2 + write_status1 + write_status2 + standby_status == 0 ) { + if( set_sleep_status + read_status1 + read_status2 + read_status3 + write_status1 + write_status2 + write_status3 + standby_status == 0 ) { return LORA_OK; } else { return LORA_FAIL; diff --git a/lora/lora.h b/lora/lora.h index 69b1168..8cefb42 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -109,10 +109,33 @@ typedef enum LORA_SPREADING_FACTOR { LORA_SPREAD_12 = 12 } LORA_SPREADING_FACTOR; +/* Datasheet page 106 */ +typedef enum LORA_BANDWIDTH { + LORA_BANDWIDTH_7_8_KHZ = 0x00, + LORA_BANDWIDTH_10_4_KHZ = 0x01, + LORA_BANDWIDTH_15_6_KHZ = 0x02, + LORA_BANDWIDTH_20_8_KHZ = 0x03, + LORA_BANDWIDTH_31_25_KHZ = 0x04, + LORA_BANDWIDTH_41_7_KHZ = 0x05, + LORA_BANDWIDTH_62_5_KHZ = 0x06, + LORA_BANDWIDTH_125_KHZ = 0x07, + LORA_BANDWIDTH_250_KHZ = 0x08, + LORA_BANDWIDTH_500_KHZ = 0x09 +} LORA_BANDWIDTH; + +typedef enum LORA_ERROR_CODING { + LORA_ECR_4_5 = 0x01, + LORA_ECR_4_6 = 0x02, + LORA_ECR_4_7 = 0x03, + LORA_ECR_4_8 = 0x04 +} LORA_ERROR_CODING; + /* LORA CONFIG SETTINGS */ typedef struct _LORA_CONFIG { LORA_CHIPMODE lora_mode; // Current LORA Chipmode LORA_SPREADING_FACTOR lora_spread; // LoRa Spread factor + LORA_BANDWIDTH lora_bandwidth; // Signal bandwith + LORA_ERROR_CODING lora_ecr; // Data Error coding } LORA_CONFIG; LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); From 3666e97f157ad074d4dcd8f2e1525e4d286b676b Mon Sep 17 00:00:00 2001 From: niekky Date: Mon, 24 Feb 2025 01:45:15 -0700 Subject: [PATCH 43/60] Added lora_transmit --- lora/lora.c | 56 +++++++++++++++++++++++++++++++++++++++-------------- lora/lora.h | 4 ++-- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 01789b6..91b69b2 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -28,6 +28,9 @@ #include "lora.h" #include "main.h" +// Debugging purposes +#include "led.h" + /*------------------------------------------------------------------------------ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ @@ -178,21 +181,46 @@ void lora_reset() { HAL_GPIO_WritePin(LORA_RST_GPIO_PORT, LORA_RST_PIN, GPIO_PIN_SET); // Pull High HAL_Delay(10); // Wait for SX1278 to stabilize } -/* -LORA_STATUS lora_transmit( uint8_t data ) { - LORA_STATUS data_write = lora_write_register( LORA_REG_FIFO_RW, 255 ); - LORA_STATUS chip_mode_status = lora_set_chip_mode( LORA_TRANSMIT_MODE ); +LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ + // Mode request STAND-BY + LORA_STATUS status = lora_set_chip_mode(LORA_STANDBY_MODE); - uint8_t transmit_status = 0b00000000; // This variable holds the IRQ register, which is checked for transmit done flag - while( ( transmit_status & 0b00010000 ) != 0b00010000 ) { // We use this bitmask to check the 4th bit to see if transmission is done - lora_read_register( LORA_REG_LORA_STATE_FLAGS, &transmit_status ); - } + // TX Init TODO - if ( data_write + chip_mode_status == 0){ - return LORA_OK; - } else { - return LORA_FAIL; + // Write data to LoRA FIFO + uint8_t fifo_ptr_addr; + LORA_STATUS status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer + if (status != LORA_OK){ + // Error handler + led_set_color(LED_RED); } -} -*/ \ No newline at end of file + LORA_STATUS status = lora_write_register(LORA_REG_FIFO_TX_BASE_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address + if (status != LORA_OK){ + // Error handler + led_set_color(LED_RED); + } + // Write buffer length to fifo_rw + LORA_STATUS status = lora_write_register(LORA_REG_FIFO_RW, buffer_len); + LORA_STATUS status = lora_set_chip_mode(LORA_TRANSMIT_MODE); + while (1){ + uint8_t lora_op + LORA_STATUS status = lora_read_register(LORA_REG_OPERATION_MODE, &lora_op); + if ((lora_op & 0b111) == LORA_STANDBY_MODE){ + break; + } + } + // Send each byte of the buffer + for (int i = 0; i Date: Tue, 25 Feb 2025 01:12:18 -0700 Subject: [PATCH 44/60] Added single mode lora receiver --- lora/lora.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lora/lora.h | 9 ++++-- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 91b69b2..c762b8f 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -182,6 +182,9 @@ void lora_reset() { HAL_Delay(10); // Wait for SX1278 to stabilize } +// ============================================================================= +// lora_transmit: transmit a buffer through lora fifo +// ============================================================================= LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ // Mode request STAND-BY LORA_STATUS status = lora_set_chip_mode(LORA_STANDBY_MODE); @@ -223,4 +226,82 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ } } return LORA_OK; +} + +// ============================================================================= +// lora_receive: receive a buffer from lora fifo with single mode +// ============================================================================= +LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ + uint8_t timeout_flag; + uint8_t rx_done; + + // Mode request STAND-BY + LORA_STATUS status = lora_set_chip_mode(LORA_STANDBY_MODE); + + // RX Init TODO + + // Set lora fifo pointer to the RX base address + uint8_t fifo_ptr_addr; + LORA_STATUS status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer + if (status != LORA_OK){ + // Error handler + led_set_color(LED_RED); + } + LORA_STATUS status = lora_write_register(LORA_REG_FIFO_RX_BASE_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address + if (status != LORA_OK){ + // Error handler + led_set_color(LED_RED); + } + + // Send request for RX Single mode + LORA_STATUS status = lora_set_chip_mode(LORA_RX_SINGLE_MODE); + + // Wait for LoRA IRQ + uint16_t timeout = 0; + while(timeout<10000){ + uint8_t irq_flag; + LORA_STATUS status = lora_read_register(LORA_REG_IRQ_FLAGS, &irq_flag); + timeout_flag = (irq_flag & (1<<7)) >> 7; + rx_done = (irq_flag & (1<<6)) >> 6; + + if (timeout_flag){ + return LORA_TIMEOUT; + } else if (rx_done) { + break; + } + timeout++; + } + + if (rx_done){ + LORA_STATUS status = lora_read_register(LORA_REG_IRQ_FLAGS, &irq_flag); + uint8_t crc_err = (irq_flag & (1<<5)) >> 5; + + if (!crc_err){ + // Read received number of bytes + uint8_t num_bytes; + LORA_STATUS status = lora_read_register(LORA_REG_FIFO_RX_NUM_BYTES, &num_bytes); + + // Set lora fifo pointer to the RX base current address + uint8_t fifo_ptr_addr; + LORA_STATUS status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer + if (status != LORA_OK){ + // Error handler + led_set_color(LED_RED); + } + LORA_STATUS status = lora_write_register(LORA_REG_FIFO_RX_BASE_CUR_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address + if (status != LORA_OK){ + // Error handler + led_set_color(LED_RED); + } + // Begin extracting payload + for (int i = 0; i < num_bytes; i++){ + uint8_t packet; + LORA_STATUS status = lora_read_register(LORA_REG_FIFO_RW, &packet); // Access LoRA FIFO data buffer pointer + buffer_ptr[i] = packet; + } + *buffer_len_ptr = num_bytes; + } + return LORA_OK; + } + return LORA_FAIL; } \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index f2e6014..a26006e 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -63,10 +63,10 @@ typedef enum LORA_REGISTER_ADDR { LORA_REG_FIFO_SPI_POINTER = 0x0D, LORA_REG_FIFO_TX_BASE_ADDR = 0x0E, LORA_REG_FIFO_RX_BASE_ADDR = 0x0F, - LORA_REG_LORA_STATE_FLAGS = 0x10, + LORA_REG_FIFO_RX_BASE_CUR_ADDR = 0x10, LORA_REG_LORA_FLAG_MASK = 0x11, - LORA_REG_INTERMEDIATE_FREQ_MSB = 0x12, - LORA_REG_INTERMEDIATE_FREQ_LSB = 0x13, + LORA_REG_IRQ_FLAGS = 0x12, + LORA_REG_FIFO_RX_NUM_BYTES = 0x13, LORA_REG_RCV_TIMEOUT_MSB = 0x14, LORA_REG_RCV_TIMEOUT_LSB = 0x15, LORA_REG_TRANS_CONFIG = 0x16, @@ -133,6 +133,9 @@ LORA_STATUS lora_init(); void lora_reset(); +LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ +LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ + // LORA_STATUS lora_transmit( uint8_t data ); #endif \ No newline at end of file From babe0086c3bef54dd8854517e3c8dfc2b3b53464 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 28 Feb 2025 15:05:12 -0700 Subject: [PATCH 45/60] Add frequency, header type to LoRa config --- lora/lora.c | 12 +++++++++++- lora/lora.h | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lora/lora.c b/lora/lora.c index f8cb34e..93ce747 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -166,11 +166,21 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { // Get initial value of config register 1 uint8_t modem_config1_register; LORA_STATUS read_status3 = lora_read_register( LORA_REG_NUM_RX_BYTES, &modem_config1_register ); - uint8_t new_config1_register = ( (lora_config_ptr->lora_bandwidth << 4) | (lora_config_ptr->lora_ecr << 1) | ( 0x01 & modem_config1_register ) ); //TODO: Check datasheet for that last bit + 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 // Write new config1 register LORA_STATUS write_status3 = lora_write_register( LORA_REG_NUM_RX_BYTES, new_config1_register ); + // Determine register values for the frequency registers + uint8_t lora_freq_reg1 = ( lora_config_ptr->lora_frequency << 8 ) >> 24; + uint8_t lora_freq_reg2 = ( lora_config_ptr->lora_frequency << 16 ) >> 24; + uint8_t lora_freq_reg3 = ( lora_config_ptr->lora_frequency << 24 ) >> 24; + + // Write the frequncy registers + LORA_STATUS write_status4 = lora_write_register( LORA_FREQ_MSB, lora_freq_reg1 ); + LORA_STATUS write_status5 = lora_write_register( LORA_FREQ_MSD, lora_freq_reg2 ); + LORA_STATUS write_status6 = lora_write_register( LORA_FREQ_LSB, lora_freq_reg3 ); + LORA_STATUS standby_status = lora_set_chip_mode( lora_config_ptr->lora_mode ); // Switch it into standby mode, which is what's convenient. if( set_sleep_status + read_status1 + read_status2 + read_status3 + write_status1 + write_status2 + write_status3 + standby_status == 0 ) { diff --git a/lora/lora.h b/lora/lora.h index 8cefb42..2dfbbc9 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -130,12 +130,21 @@ typedef enum LORA_ERROR_CODING { LORA_ECR_4_8 = 0x04 } LORA_ERROR_CODING; +typedef enum LORA_HEADER_MODE {// You can see this on 106 - what this actually means is on pages 26 and 27 + LORA_IMPLICIT_HEADER = 0b1, + LORA_EXPLICIT_HEADER = 0b0 +} LORA_HEADER_MODE; + /* LORA CONFIG SETTINGS */ typedef struct _LORA_CONFIG { LORA_CHIPMODE lora_mode; // Current LORA Chipmode LORA_SPREADING_FACTOR lora_spread; // LoRa Spread factor LORA_BANDWIDTH lora_bandwidth; // Signal bandwith LORA_ERROR_CODING lora_ecr; // Data Error coding + LORA_HEADER_MODE lora_header_mode; // LORA Header mode + uint32_t lora_frequency; // The LORA carrier frequency. This is NOT directly in megahertz. (See datasheet page 103) + // To convert, use the formula (2^19 * x)/(32 * 10^6) + // This library provides a helper function } LORA_CONFIG; LORA_STATUS LORA_SPI_Receive( uint8_t* read_buffer_ptr ); @@ -156,6 +165,12 @@ LORA_STATUS lora_init(); void lora_reset(); + +// Convert a human-readable frequency to the unit used internally by the modem +uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { + return ( (2^19) * x )/( 32 * 10^6 ); +} + // LORA_STATUS lora_transmit( uint8_t data ); #endif \ No newline at end of file From f7b89b45397f0f103f1f2494ab7b9bb598c19d9c Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 28 Feb 2025 15:14:55 -0700 Subject: [PATCH 46/60] Add missing power of 10 to mhz conversion function --- lora/lora.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lora/lora.h b/lora/lora.h index 2dfbbc9..d460f62 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -168,7 +168,7 @@ void lora_reset(); // Convert a human-readable frequency to the unit used internally by the modem uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { - return ( (2^19) * x )/( 32 * 10^6 ); + return ( (2^19) * x * 10^6 )/( 32 * 10^6 ); } // LORA_STATUS lora_transmit( uint8_t data ); From 11540ac08645b0dc1a724c9edf8035f9bcef37f6 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 28 Feb 2025 15:18:31 -0700 Subject: [PATCH 47/60] Fix several typos --- lora/lora.c | 13 +++++++++---- lora/lora.h | 4 +--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 93ce747..c5427d6 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -177,13 +177,13 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { uint8_t lora_freq_reg3 = ( lora_config_ptr->lora_frequency << 24 ) >> 24; // Write the frequncy registers - LORA_STATUS write_status4 = lora_write_register( LORA_FREQ_MSB, lora_freq_reg1 ); - LORA_STATUS write_status5 = lora_write_register( LORA_FREQ_MSD, lora_freq_reg2 ); - LORA_STATUS write_status6 = lora_write_register( LORA_FREQ_LSB, lora_freq_reg3 ); + LORA_STATUS write_status4 = lora_write_register( LORA_REG_FREQ_MSB, lora_freq_reg1 ); + LORA_STATUS write_status5 = lora_write_register( LORA_REG_FREQ_MSD, lora_freq_reg2 ); + LORA_STATUS write_status6 = lora_write_register( LORA_REG_FREQ_LSB, lora_freq_reg3 ); LORA_STATUS standby_status = lora_set_chip_mode( lora_config_ptr->lora_mode ); // Switch it into standby mode, which is what's convenient. - if( set_sleep_status + read_status1 + read_status2 + read_status3 + write_status1 + write_status2 + write_status3 + standby_status == 0 ) { + if( set_sleep_status + read_status1 + read_status2 + read_status3 + write_status1 + write_status2 + write_status3 + write_status4 + write_status5 + write_status6 + standby_status == 0 ) { return LORA_OK; } else { return LORA_FAIL; @@ -196,6 +196,11 @@ void lora_reset() { HAL_GPIO_WritePin(LORA_RST_GPIO_PORT, LORA_RST_PIN, GPIO_PIN_SET); // Pull High HAL_Delay(10); // Wait for SX1278 to stabilize } + +uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { + return ( (2^19) * mhz_freq * 10^6 )/( 32 * 10^6 ); +} + /* LORA_STATUS lora_transmit( uint8_t data ) { LORA_STATUS data_write = lora_write_register( LORA_REG_FIFO_RW, 255 ); diff --git a/lora/lora.h b/lora/lora.h index d460f62..88d392c 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -167,9 +167,7 @@ void lora_reset(); // Convert a human-readable frequency to the unit used internally by the modem -uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { - return ( (2^19) * x * 10^6 )/( 32 * 10^6 ); -} +uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ); // LORA_STATUS lora_transmit( uint8_t data ); From 538ed968e4d4fd43b9b2eb64fcd11d020d3d153c Mon Sep 17 00:00:00 2001 From: niekky Date: Fri, 28 Feb 2025 15:54:11 -0700 Subject: [PATCH 48/60] Delete redundancy --- .vscode/settings.json | 5 +++++ lora/lora.c | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..af13e3a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "cstdint": "cpp" + } +} \ No newline at end of file diff --git a/lora/lora.c b/lora/lora.c index c5427d6..f1f96e6 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -117,15 +117,13 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { // Get initial value of the operation mode register uint8_t operation_mode_register; LORA_STATUS read_status = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); - // if( read_status & 0b00000001 != 0b00000001 ) { // Make function automatically fail if chip is not in LoRa mode - // return LORA_FAIL; - // } if (read_status != LORA_OK) { return LORA_FAIL; } + // Fail if not in LORA Mode if ( !( operation_mode_register & (1<<7) ) ){ return LORA_FAIL; } From b442c833c51e1f531070e5c1e9f3ddf5cd8b7e31 Mon Sep 17 00:00:00 2001 From: niekky Date: Fri, 7 Mar 2025 00:54:23 -0700 Subject: [PATCH 49/60] Added flight ground controller identifier code --- commands/commands.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/commands.h b/commands/commands.h index 1dfafd1..b4d797f 100644 --- a/commands/commands.h +++ b/commands/commands.h @@ -70,7 +70,7 @@ extern "C" { #define FIRMWARE_HOTFIRE ( 0x04 ) /* Hotfire Firmware */ #define FIRMWARE_GD_TRANSMITTER ( 0x05 ) /* Transmitter Firmware */ #define FIRMWARE_GD_RECEIVER ( 0x06 ) /* Receiver Firmware */ - +#define FIRMWARE_FGD_TRANSMITTER ( 0x07 ) /* Flgiht Transmitter Firmware */ /*------------------------------------------------------------------------------ Function Prototypes ------------------------------------------------------------------------------*/ From 8cfc4a57ebf62b9b632ba4d6a2b984f59907975c Mon Sep 17 00:00:00 2001 From: niekky Date: Fri, 7 Mar 2025 01:00:22 -0700 Subject: [PATCH 50/60] Modified revision identifier code --- commands/commands.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/commands.h b/commands/commands.h index b4d797f..bbe342c 100644 --- a/commands/commands.h +++ b/commands/commands.h @@ -58,7 +58,7 @@ extern "C" { #elif defined ( A0005_REV2 ) /* Ground Station Rev 2.0 */ /* Rev 2 */ #define PING_RESPONSE_CODE ( 0x09 ) -#elif defined ( A0005_REV1 ) /* Flight Ground Station Rev */ +#elif defined ( A0005_REV3 ) /* Flight Ground Station Rev */ #define PING_RESPONSE_CODE ( 0xA0 ) #endif From e678224b7a3cdb138d4976d2885fcc9810638c30 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 7 Mar 2025 13:19:54 -0700 Subject: [PATCH 51/60] Make transmit, receive functions compile --- lora/lora.c | 98 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 6483ab6..9878c78 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -198,58 +198,65 @@ void lora_reset() { HAL_Delay(10); // Wait for SX1278 to stabilize } -uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { - return ( (2^19) * mhz_freq * 10^6 )/( 32 * 10^6 ); -} - - LORA_STATUS lora_transmit( uint8_t data ) { LORA_STATUS data_write = lora_write_register( LORA_REG_FIFO_RW, 255 ); // ============================================================================= // lora_transmit: transmit a buffer through lora fifo -// ============================================================================= +// ================v============================================================= LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ // Mode request STAND-BY - LORA_STATUS status = lora_set_chip_mode(LORA_STANDBY_MODE); + LORA_STATUS standby_status = lora_set_chip_mode(LORA_STANDBY_MODE); // TX Init TODO // Write data to LoRA FIFO uint8_t fifo_ptr_addr; - LORA_STATUS status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer - if (status != LORA_OK){ + LORA_STATUS ptr_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer + if (ptr_status + standby_status != LORA_OK){ // Error handler led_set_color(LED_RED); + return LORA_FAIL; } - LORA_STATUS status = lora_write_register(LORA_REG_FIFO_TX_BASE_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address - if (status != LORA_OK){ + LORA_STATUS tx_base_status = lora_write_register(LORA_REG_FIFO_TX_BASE_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address + if (tx_base_status != LORA_OK){ // Error handler led_set_color(LED_RED); + return LORA_FAIL; } // Write buffer length to fifo_rw - LORA_STATUS status = lora_write_register(LORA_REG_FIFO_RW, buffer_len); - LORA_STATUS status = lora_set_chip_mode(LORA_TRANSMIT_MODE); - while (1){ - uint8_t lora_op - LORA_STATUS status = lora_read_register(LORA_REG_OPERATION_MODE, &lora_op); + LORA_STATUS fifo_status = lora_write_register(LORA_REG_FIFO_RW, buffer_len); + LORA_STATUS tmode_status = lora_set_chip_mode(LORA_TRANSMIT_MODE); + + uint8_t lora_op; + LORA_STATUS regop_status; + while (1){ // TODO Add a timeout here + regop_status = lora_read_register(LORA_REG_OPERATION_MODE, &lora_op); if ((lora_op & 0b111) == LORA_STANDBY_MODE){ break; } } // Send each byte of the buffer + LORA_STATUS sendbyte_status; for (int i = 0; i> 7; rx_done = (irq_flag & (1<<6)) >> 6; @@ -297,35 +307,47 @@ LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ } if (rx_done){ - LORA_STATUS status = lora_read_register(LORA_REG_IRQ_FLAGS, &irq_flag); + LORA_STATUS irq_status2 = lora_read_register(LORA_REG_IRQ_FLAGS, &irq_flag); uint8_t crc_err = (irq_flag & (1<<5)) >> 5; if (!crc_err){ // Read received number of bytes uint8_t num_bytes; - LORA_STATUS status = lora_read_register(LORA_REG_FIFO_RX_NUM_BYTES, &num_bytes); + LORA_STATUS fifo2_status = lora_read_register(LORA_REG_FIFO_RX_NUM_BYTES, &num_bytes); // Set lora fifo pointer to the RX base current address uint8_t fifo_ptr_addr; - LORA_STATUS status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer - if (status != LORA_OK){ + LORA_STATUS ptr2_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer + if (ptr2_status != LORA_OK){ // Error handler led_set_color(LED_RED); + return LORA_FAIL; } - LORA_STATUS status = lora_write_register(LORA_REG_FIFO_RX_BASE_CUR_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address - if (status != LORA_OK){ + LORA_STATUS base_adr_status = lora_write_register(LORA_REG_FIFO_RX_BASE_CUR_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address + if (base_adr_status != LORA_OK){ // Error handler led_set_color(LED_RED); + return LORA_FAIL; } // Begin extracting payload + LORA_STATUS pld_xtr_status; for (int i = 0; i < num_bytes; i++){ uint8_t packet; - LORA_STATUS status = lora_read_register(LORA_REG_FIFO_RW, &packet); // Access LoRA FIFO data buffer pointer + pld_xtr_status = lora_read_register(LORA_REG_FIFO_RW, &packet); // Access LoRA FIFO data buffer pointer buffer_ptr[i] = packet; } *buffer_len_ptr = num_bytes; - } + if( pld_xtr_status == LORA_OK ) { + return LORA_OK; + } else { + return LORA_FAIL; + } + } return LORA_OK; } return LORA_FAIL; +} + +uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { + return ( (2^19) * mhz_freq * 10^6 )/( 32 * 10^6 ); } \ No newline at end of file From 6cdc92d8983d4ee0794ec9dfc4dacdb6b68f1e04 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 7 Mar 2025 14:01:12 -0700 Subject: [PATCH 52/60] Make Lora transmit and receive functions actually compile --- lora/lora.c | 25 +++++++++++-------------- lora/lora.h | 4 ++-- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 9878c78..f801423 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -31,6 +31,13 @@ // Debugging purposes #include "led.h" +/*------------------------------------------------------------------------------ + Frequency calculation helper function +------------------------------------------------------------------------------*/ +uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { + return ( (2^19) * mhz_freq * 10^6 )/( 32 * 10^6 ); +} + /*------------------------------------------------------------------------------ Helper functions for various pin functions on the LoRa modem. ------------------------------------------------------------------------------*/ @@ -198,9 +205,6 @@ void lora_reset() { HAL_Delay(10); // Wait for SX1278 to stabilize } -LORA_STATUS lora_transmit( uint8_t data ) { - LORA_STATUS data_write = lora_write_register( LORA_REG_FIFO_RW, 255 ); - // ============================================================================= // lora_transmit: transmit a buffer through lora fifo // ================v============================================================= @@ -249,14 +253,11 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ } } } - if( fifo_status + - tmode_status + - regop_status + - sendbyte_status == 0 ) { + if( fifo_status + tmode_status + regop_status + sendbyte_status == 0 ) { return LORA_OK; - } else { - return LORA_FAIL; - } + } else { + return LORA_FAIL; + } } // ============================================================================= @@ -346,8 +347,4 @@ LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ return LORA_OK; } return LORA_FAIL; -} - -uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ) { - return ( (2^19) * mhz_freq * 10^6 )/( 32 * 10^6 ); } \ No newline at end of file diff --git a/lora/lora.h b/lora/lora.h index eb15b8b..26c7705 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -165,8 +165,8 @@ LORA_STATUS lora_init(); void lora_reset(); -LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ -LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ +LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len); +LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr); // Convert a human-readable frequency to the unit used internally by the modem uint32_t lora_helper_mhz_to_reg_val( uint32_t mhz_freq ); From da70c3bec005cd74a4d332bf9f543dee6c185c2d Mon Sep 17 00:00:00 2001 From: niekky Date: Wed, 12 Mar 2025 18:33:18 -0700 Subject: [PATCH 53/60] Critical spi hot-fixes --- lora/lora.c | 4 ++-- lora/lora.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index f801423..f4d545d 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -70,7 +70,7 @@ LORA_STATUS LORA_SPI_Transmit_Data( LORA_REGISTER_ADDR reg, uint8_t data ) { /* Takes register and data to write and writes that register. */ uint8_t transmitBuffer[2] = { reg, data }; - status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer, 1, LORA_TIMEOUT); + status = HAL_SPI_Transmit( &(LORA_SPI), &transmitBuffer[0], 2, LORA_TIMEOUT); if (status == HAL_OK){ return LORA_OK; @@ -300,7 +300,7 @@ LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ rx_done = (irq_flag & (1<<6)) >> 6; if (timeout_flag){ - return LORA_TIMEOUT; + return LORA_TIMEOUT_FAIL; } else if (rx_done) { break; } diff --git a/lora/lora.h b/lora/lora.h index 26c7705..4b60258 100644 --- a/lora/lora.h +++ b/lora/lora.h @@ -45,7 +45,8 @@ typedef enum LORA_STATUS { LORA_FAIL, // Temporary enum additions to distinguish between transmit and receive failures LORA_TRANSMIT_FAIL, - LORA_RECEIVE_FAIL + LORA_RECEIVE_FAIL, + LORA_TIMEOUT_FAIL, } LORA_STATUS; /* Radio register addresses from datasheet (https://www.mouser.com/datasheet/2/975/1463993415RFM95_96_97_98W-1858106.pdf) From cbd9ce3ccf1e81455a5830cdf1f1847e34f88d26 Mon Sep 17 00:00:00 2001 From: niekky Date: Tue, 25 Mar 2025 01:34:13 -0700 Subject: [PATCH 54/60] Fixed set chip mode --- lora/lora.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index f4d545d..852f32f 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -133,14 +133,15 @@ LORA_STATUS lora_set_chip_mode( LORA_CHIPMODE chip_mode ) { return LORA_FAIL; } - // Fail if not in LORA Mode - if ( !( operation_mode_register & (1<<7) ) ){ - return LORA_FAIL; - } + // // Fail if not in LORA Mode + // if ( !( operation_mode_register & (1<<7) ) ){ + // return LORA_FAIL; + // } // Change the value of the chip register to set it to the suggested chip mode - uint8_t new_opmode_register = (operation_mode_register | chip_mode); - + uint8_t new_opmode_register = (operation_mode_register & ~(0x7)); + new_opmode_register = (new_opmode_register | chip_mode); + // Write new byte LORA_STATUS write_status = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); @@ -158,7 +159,7 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { LORA_STATUS read_status1 = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); uint8_t new_opmode_register; - new_opmode_register = ( operation_mode_register | 0b00000001 ); // Toggle the LoRa bit + new_opmode_register = ( operation_mode_register | 0b10000000 ); // Toggle the LoRa bit // Write new byte LORA_STATUS write_status1 = lora_write_register( LORA_REG_OPERATION_MODE, new_opmode_register ); From d053e6c70f397efcd72ff106260348380ceaa9d7 Mon Sep 17 00:00:00 2001 From: niekky Date: Tue, 25 Mar 2025 01:56:19 -0700 Subject: [PATCH 55/60] Fixed config2 write and frequecy registers --- lora/lora.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 852f32f..6d7820c 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -169,7 +169,7 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { LORA_STATUS read_status2 = lora_read_register( LORA_REG_RX_HEADER_INFO, &modem_config2_register ); uint8_t new_config2_register = modem_config2_register & 0x0F; // Erase spread factor bits - new_config2_register = ( modem_config2_register | ( lora_config_ptr->lora_spread << 4 ) ); // Set the spread factor + new_config2_register = ( new_config2_register | ( lora_config_ptr->lora_spread << 4 ) ); // Set the spread factor LORA_STATUS write_status2 = lora_write_register( LORA_REG_RX_HEADER_INFO, new_config2_register ); // Write new spread factor // Get initial value of config register 1 @@ -181,16 +181,18 @@ LORA_STATUS lora_init( LORA_CONFIG *lora_config_ptr ) { LORA_STATUS write_status3 = lora_write_register( LORA_REG_NUM_RX_BYTES, new_config1_register ); // Determine register values for the frequency registers - uint8_t lora_freq_reg1 = ( lora_config_ptr->lora_frequency << 8 ) >> 24; - uint8_t lora_freq_reg2 = ( lora_config_ptr->lora_frequency << 16 ) >> 24; - uint8_t lora_freq_reg3 = ( lora_config_ptr->lora_frequency << 24 ) >> 24; + uint32_t frf_reg = lora_config_ptr->lora_frequency * 524288 / 32; + + uint8_t lora_freq_reg1 = ( frf_reg << 8 ) >> 24; + uint8_t lora_freq_reg2 = ( frf_reg << 16 ) >> 24; + uint8_t lora_freq_reg3 = ( frf_reg << 24 ) >> 24; // Write the frequncy registers LORA_STATUS write_status4 = lora_write_register( LORA_REG_FREQ_MSB, lora_freq_reg1 ); LORA_STATUS write_status5 = lora_write_register( LORA_REG_FREQ_MSD, lora_freq_reg2 ); LORA_STATUS write_status6 = lora_write_register( LORA_REG_FREQ_LSB, lora_freq_reg3 ); - LORA_STATUS standby_status = lora_set_chip_mode( lora_config_ptr->lora_mode ); // Switch it into standby mode, which is what's convenient. + LORA_STATUS standby_status = lora_set_chip_mode( LORA_STANDBY_MODE ); // Switch it into standby mode, which is what's convenient. if( set_sleep_status + read_status1 + read_status2 + read_status3 + write_status1 + write_status2 + write_status3 + write_status4 + write_status5 + write_status6 + standby_status == 0 ) { return LORA_OK; From 81c6d720d30ff9d7fc1b54775718b0f9b99c20c2 Mon Sep 17 00:00:00 2001 From: niekky Date: Wed, 26 Mar 2025 10:23:43 -0700 Subject: [PATCH 56/60] Testing Transmit --- lora/lora.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 6d7820c..bf8a4f3 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -217,6 +217,10 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ // TX Init TODO + /* TESTING PURPOSE */ + uint8_t operation_mode_register; + LORA_STATUS read_status1 = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); + // Write data to LoRA FIFO uint8_t fifo_ptr_addr; LORA_STATUS ptr_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer @@ -231,10 +235,21 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ led_set_color(LED_RED); return LORA_FAIL; } + + // Send byte to byte to the fifo buffer + LORA_STATUS sendbyte_status; + for (int i = 0; i Date: Wed, 26 Mar 2025 23:01:51 -0700 Subject: [PATCH 57/60] Removed typo --- lora/lora.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lora/lora.c b/lora/lora.c index bf8a4f3..998eb5b 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -258,7 +258,6 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ break; } } - / if( fifo_status + tmode_status + regop_status + sendbyte_status == 0 ) { return LORA_OK; } else { From bfd8672aa25f8f9daece3946eb8f08e85eb9b369 Mon Sep 17 00:00:00 2001 From: niekky Date: Thu, 27 Mar 2025 00:29:38 -0700 Subject: [PATCH 58/60] Tested lora_transmit --- lora/lora.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 998eb5b..2e437c5 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -212,15 +212,11 @@ void lora_reset() { // lora_transmit: transmit a buffer through lora fifo // ================v============================================================= LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ + uint8_t fifo_ptr_addr_test; // Testing fifo increment + // Mode request STAND-BY LORA_STATUS standby_status = lora_set_chip_mode(LORA_STANDBY_MODE); - // TX Init TODO - - /* TESTING PURPOSE */ - uint8_t operation_mode_register; - LORA_STATUS read_status1 = lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); - // Write data to LoRA FIFO uint8_t fifo_ptr_addr; LORA_STATUS ptr_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer @@ -242,14 +238,23 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ sendbyte_status = lora_write_register(LORA_REG_FIFO_RW, buffer_ptr[i]); /* TESTING PURPOSE */ - uint8_t fifo_ptr_addr_test; LORA_STATUS ptr_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr_test); // Access LoRA FIFO data buffer pointer } // Write buffer length to fifo_rw LORA_STATUS fifo_status = lora_write_register(LORA_REG_SIGNAL_TO_NOISE, buffer_len); + /* TESTING PURPOSE: Read payload length */ + uint8_t test_buf; + lora_read_register( LORA_REG_SIGNAL_TO_NOISE, &test_buf ); + LORA_STATUS tmode_status = lora_set_chip_mode(LORA_TRANSMIT_MODE); + + /* TESTING PURPOSE: Test op mode transition */ + uint8_t operation_mode_register; + lora_read_register( LORA_REG_OPERATION_MODE, &operation_mode_register ); + + uint8_t lora_op; LORA_STATUS regop_status; while (1){ // TODO Add a timeout here From 9a7d0373c35b78d13e26fac62da6de2efce09107 Mon Sep 17 00:00:00 2001 From: Dexx Stexx Date: Fri, 11 Apr 2025 13:07:53 -0700 Subject: [PATCH 59/60] Move buffer length --- lora/lora.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 2e437c5..8394296 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -232,6 +232,9 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ return LORA_FAIL; } + // Write buffer length to fifo_rw + LORA_STATUS fifo_status = lora_write_register(LORA_REG_SIGNAL_TO_NOISE, buffer_len); + // Send byte to byte to the fifo buffer LORA_STATUS sendbyte_status; for (int i = 0; i Date: Mon, 22 Sep 2025 13:00:51 -0700 Subject: [PATCH 60/60] Temporarily disable LED functionality in LoRa --- lora/lora.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lora/lora.c b/lora/lora.c index 8394296..82573b2 100644 --- a/lora/lora.c +++ b/lora/lora.c @@ -29,7 +29,7 @@ #include "main.h" // Debugging purposes -#include "led.h" +// #include "led.h" /*------------------------------------------------------------------------------ Frequency calculation helper function @@ -222,13 +222,13 @@ LORA_STATUS lora_transmit(uint8_t* buffer_ptr, uint8_t buffer_len){ LORA_STATUS ptr_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer if (ptr_status + standby_status != LORA_OK){ // Error handler - led_set_color(LED_RED); + // led_set_color(// led_RED); return LORA_FAIL; } LORA_STATUS tx_base_status = lora_write_register(LORA_REG_FIFO_TX_BASE_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address if (tx_base_status != LORA_OK){ // Error handler - led_set_color(LED_RED); + // led_set_color(// led_RED); return LORA_FAIL; } @@ -287,13 +287,13 @@ LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ LORA_STATUS ptr_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer if (standby_status + ptr_status != LORA_OK){ // Error handler - led_set_color(LED_RED); + // led_set_color(// led_RED); return LORA_FAIL; } LORA_STATUS fifo_status = lora_write_register(LORA_REG_FIFO_RX_BASE_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address if (fifo_status != LORA_OK){ // Error handler - led_set_color(LED_RED); + // led_set_color(// led_RED); return LORA_FAIL; } @@ -331,13 +331,13 @@ LORA_STATUS lora_receive(uint8_t* buffer_ptr, uint8_t* buffer_len_ptr){ LORA_STATUS ptr2_status = lora_read_register(LORA_REG_FIFO_SPI_POINTER, &fifo_ptr_addr); // Access LoRA FIFO data buffer pointer if (ptr2_status != LORA_OK){ // Error handler - led_set_color(LED_RED); + // led_set_color(// led_RED); return LORA_FAIL; } LORA_STATUS base_adr_status = lora_write_register(LORA_REG_FIFO_RX_BASE_CUR_ADDR, fifo_ptr_addr); // Set fifo data pointer to TX base address if (base_adr_status != LORA_OK){ // Error handler - led_set_color(LED_RED); + // led_set_color(// led_RED); return LORA_FAIL; } // Begin extracting payload