Merge pull request #4 from wdomski/develop

Updated documentation
This commit is contained in:
Wojciech Domski 2020-10-21 20:22:20 +02:00 committed by GitHub
commit d6d89363ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 461 additions and 138 deletions

View File

@ -9,12 +9,36 @@ The initial work was based on DORJI.COM sample code and [SX1278_LoRa](https://gi
The driver was written in **C**. It has a hardware abstraction layer for easy porting to others MCUs.
Also the hardware functions are defined as *__weak* so there is no need to change the driver files themselves.
The driver is using HAL to communicate between STM32 SPI periperal and LoRa module.
The driver is using HAL to communicate between STM32 SPI peripheral and LoRa module.
# Example
There is also an example available at [SX1278-example repository](https://github.com/wdomski/SX1278-example).
The example project was prepared for STM32F1 MCU in SW4STM32.
The example project was initially prepared for STM32F1 MCU in SW4STM32.
Consult the *README* file in the above repository which development
board is currently supported.
# Documentation
The driver is quite simple to use and now requires even lower entry
level. After collecting some feedback from my blog readers I decided
to include some more features including automatic frequency setting.
Previously, it was done by manually calculating values which
should be written to the LoRa module's registers. Now, the frequency
can be set during initialization by passing an argument to the
function.
Since the driver is rather small the documentation (at least the
most common parts) will be included here.
## Hardware layer
The driver can be easily ported to a different platform with
minimum effort. Only the hardware dependant functions ought to be
modified. The hardware dependant parts can be find in
**SX1278_hw.c** and **SX1278_hw.h**.
## Logic layer
# Final remarks

View File

@ -9,65 +9,7 @@
#include "SX1278.h"
#include <string.h>
#include "gpio.h"
#include "spi.h"
//////////////////////////////////
// logic
//////////////////////////////////
__weak void SX1278_hw_init(SX1278_hw_t * hw) {
SX1278_hw_SetNSS(hw, 1);
HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_SET);
}
__weak void SX1278_hw_SetNSS(SX1278_hw_t * hw, int value) {
HAL_GPIO_WritePin(hw->nss.port, hw->nss.pin,
(value == 1) ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
__weak void SX1278_hw_Reset(SX1278_hw_t * hw) {
SX1278_hw_SetNSS(hw, 1);
HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_RESET);
SX1278_hw_DelayMs(1);
HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_SET);
SX1278_hw_DelayMs(100);
}
__weak void SX1278_hw_SPICommand(SX1278_hw_t * hw, uint8_t cmd) {
SX1278_hw_SetNSS(hw, 0);
HAL_SPI_Transmit(hw->spi, &cmd, 1, 1000);
while (HAL_SPI_GetState(hw->spi) != HAL_SPI_STATE_READY)
;
}
__weak uint8_t SX1278_hw_SPIReadByte(SX1278_hw_t * hw) {
uint8_t txByte = 0x00;
uint8_t rxByte = 0x00;
SX1278_hw_SetNSS(hw, 0);
HAL_SPI_TransmitReceive(hw->spi, &txByte, &rxByte, 1, 1000);
while (HAL_SPI_GetState(hw->spi) != HAL_SPI_STATE_READY)
;
return rxByte;
}
__weak void SX1278_hw_DelayMs(uint32_t msec) {
HAL_Delay(msec);
}
__weak int SX1278_hw_GetDIO0(SX1278_hw_t * hw) {
return (HAL_GPIO_ReadPin(hw->dio0.port, hw->dio0.pin) == GPIO_PIN_SET);
}
//////////////////////////////////
// logic
//////////////////////////////////
uint8_t SX1278_SPIRead(SX1278_t * module, uint8_t addr) {
uint8_t SX1278_SPIRead(SX1278_t *module, uint8_t addr) {
uint8_t tmp;
SX1278_hw_SPICommand(module->hw, addr);
tmp = SX1278_hw_SPIReadByte(module->hw);
@ -75,14 +17,14 @@ uint8_t SX1278_SPIRead(SX1278_t * module, uint8_t addr) {
return tmp;
}
void SX1278_SPIWrite(SX1278_t * module, uint8_t addr, uint8_t cmd) {
void SX1278_SPIWrite(SX1278_t *module, uint8_t addr, uint8_t cmd) {
SX1278_hw_SetNSS(module->hw, 0);
SX1278_hw_SPICommand(module->hw, addr | 0x80);
SX1278_hw_SPICommand(module->hw, cmd);
SX1278_hw_SetNSS(module->hw, 1);
}
void SX1278_SPIBurstRead(SX1278_t * module, uint8_t addr, uint8_t * rxBuf,
void SX1278_SPIBurstRead(SX1278_t *module, uint8_t addr, uint8_t *rxBuf,
uint8_t length) {
uint8_t i;
if (length <= 1) {
@ -97,7 +39,7 @@ void SX1278_SPIBurstRead(SX1278_t * module, uint8_t addr, uint8_t * rxBuf,
}
}
void SX1278_SPIBurstWrite(SX1278_t * module, uint8_t addr, uint8_t * txBuf,
void SX1278_SPIBurstWrite(SX1278_t *module, uint8_t addr, uint8_t *txBuf,
uint8_t length) {
unsigned char i;
if (length <= 1) {
@ -112,7 +54,7 @@ void SX1278_SPIBurstWrite(SX1278_t * module, uint8_t addr, uint8_t * txBuf,
}
}
void SX1278_config(SX1278_t * module) {
void SX1278_config(SX1278_t *module) {
SX1278_sleep(module); //Change modem mode Must in Sleep mode
SX1278_hw_DelayMs(15);
@ -133,16 +75,16 @@ void SX1278_config(SX1278_t * module) {
SX1278_SPIWrite(module, LR_RegOcp, 0x0B); //RegOcp,Close Ocp
SX1278_SPIWrite(module, LR_RegLna, 0x23); //RegLNA,High & LNA Enable
if (SX1278_SpreadFactor[module->LoRa_Rate] == 6) { //SFactor=6
if (SX1278_SpreadFactor[module->LoRa_SF] == 6) { //SFactor=6
uint8_t tmp;
SX1278_SPIWrite(module,
LR_RegModemConfig1,
((SX1278_LoRaBandwidth[module->LoRa_BW] << 4) + (SX1278_CodingRate[module->LoRa_CR] << 1)
+ 0x01)); //Implicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
((SX1278_LoRaBandwidth[module->LoRa_BW] << 4)
+ (SX1278_CodingRate[module->LoRa_CR] << 1) + 0x01)); //Implicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
SX1278_SPIWrite(module,
LR_RegModemConfig2,
((SX1278_SpreadFactor[module->LoRa_Rate] << 4)
((SX1278_SpreadFactor[module->LoRa_SF] << 4)
+ (SX1278_CRC_Sum[module->LoRa_CRC_sum] << 2) + 0x03));
tmp = SX1278_SPIRead(module, 0x31);
@ -153,12 +95,12 @@ void SX1278_config(SX1278_t * module) {
} else {
SX1278_SPIWrite(module,
LR_RegModemConfig1,
((SX1278_LoRaBandwidth[module->LoRa_BW] << 4) + (SX1278_CodingRate[module->LoRa_CR] << 1)
+ 0x00)); //Explicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
((SX1278_LoRaBandwidth[module->LoRa_BW] << 4)
+ (SX1278_CodingRate[module->LoRa_CR] << 1) + 0x00)); //Explicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
SX1278_SPIWrite(module,
LR_RegModemConfig2,
((SX1278_SpreadFactor[module->LoRa_Rate] << 4)
((SX1278_SpreadFactor[module->LoRa_SF] << 4)
+ (SX1278_CRC_Sum[module->LoRa_CRC_sum] << 2) + 0x00)); //SFactor & LNA gain set by the internal AGC loop
}
@ -171,25 +113,25 @@ void SX1278_config(SX1278_t * module) {
SX1278_standby(module); //Entry standby mode
}
void SX1278_standby(SX1278_t * module) {
void SX1278_standby(SX1278_t *module) {
SX1278_SPIWrite(module, LR_RegOpMode, 0x09);
module->status = STANDBY;
}
void SX1278_sleep(SX1278_t * module) {
void SX1278_sleep(SX1278_t *module) {
SX1278_SPIWrite(module, LR_RegOpMode, 0x08);
module->status = SLEEP;
}
void SX1278_entryLoRa(SX1278_t * module) {
void SX1278_entryLoRa(SX1278_t *module) {
SX1278_SPIWrite(module, LR_RegOpMode, 0x88);
}
void SX1278_clearLoRaIrq(SX1278_t * module) {
void SX1278_clearLoRaIrq(SX1278_t *module) {
SX1278_SPIWrite(module, LR_RegIrqFlags, 0xFF);
}
int SX1278_LoRaEntryRx(SX1278_t * module, uint8_t length, uint32_t timeout) {
int SX1278_LoRaEntryRx(SX1278_t *module, uint8_t length, uint32_t timeout) {
uint8_t addr;
module->packetLength = length;
@ -221,7 +163,7 @@ int SX1278_LoRaEntryRx(SX1278_t * module, uint8_t length, uint32_t timeout) {
}
}
uint8_t SX1278_LoRaRxPacket(SX1278_t * module) {
uint8_t SX1278_LoRaRxPacket(SX1278_t *module) {
unsigned char addr;
unsigned char packet_size;
@ -231,7 +173,7 @@ uint8_t SX1278_LoRaRxPacket(SX1278_t * module) {
addr = SX1278_SPIRead(module, LR_RegFifoRxCurrentaddr); //last packet addr
SX1278_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RxBaseAddr -> FiFoAddrPtr
if (module->LoRa_Rate == SX1278_LORA_SF_6) { //When SpreadFactor is six,will used Implicit Header mode(Excluding internal packet length)
if (module->LoRa_SF == SX1278_LORA_SF_6) { //When SpreadFactor is six,will used Implicit Header mode(Excluding internal packet length)
packet_size = module->packetLength;
} else {
packet_size = SX1278_SPIRead(module, LR_RegRxNbBytes); //Number for received bytes
@ -244,7 +186,7 @@ uint8_t SX1278_LoRaRxPacket(SX1278_t * module) {
return module->readBytes;
}
int SX1278_LoRaEntryTx(SX1278_t * module, uint8_t length, uint32_t timeout) {
int SX1278_LoRaEntryTx(SX1278_t *module, uint8_t length, uint32_t timeout) {
uint8_t addr;
uint8_t temp;
@ -275,7 +217,7 @@ int SX1278_LoRaEntryTx(SX1278_t * module, uint8_t length, uint32_t timeout) {
}
}
int SX1278_LoRaTxPacket(SX1278_t * module, uint8_t * txBuffer, uint8_t length,
int SX1278_LoRaTxPacket(SX1278_t *module, uint8_t *txBuffer, uint8_t length,
uint32_t timeout) {
SX1278_SPIBurstWrite(module, 0x00, txBuffer, length);
SX1278_SPIWrite(module, LR_RegOpMode, 0x8b); //Tx Mode
@ -296,12 +238,13 @@ int SX1278_LoRaTxPacket(SX1278_t * module, uint8_t * txBuffer, uint8_t length,
}
}
void SX1278_init(SX1278_t * module, uint64_t frequency, uint8_t power,
uint8_t LoRa_Rate, uint8_t LoRa_BW, uint8_t LoRa_CR, uint8_t LoRa_CRC_sum, uint8_t packetLength) {
void SX1278_init(SX1278_t *module, uint64_t frequency, uint8_t power,
uint8_t LoRa_SF, uint8_t LoRa_BW, uint8_t LoRa_CR,
uint8_t LoRa_CRC_sum, uint8_t packetLength) {
SX1278_hw_init(module->hw);
module->frequency = frequency;
module->power = power;
module->LoRa_Rate = LoRa_Rate;
module->LoRa_SF = LoRa_SF;
module->LoRa_BW = LoRa_BW;
module->LoRa_CR = LoRa_CR;
module->LoRa_CRC_sum = LoRa_CRC_sum;
@ -309,7 +252,7 @@ void SX1278_init(SX1278_t * module, uint64_t frequency, uint8_t power,
SX1278_config(module);
}
int SX1278_transmit(SX1278_t * module, uint8_t * txBuf, uint8_t length,
int SX1278_transmit(SX1278_t *module, uint8_t *txBuf, uint8_t length,
uint32_t timeout) {
if (SX1278_LoRaEntryTx(module, length, timeout)) {
return SX1278_LoRaTxPacket(module, txBuf, length, timeout);
@ -317,15 +260,15 @@ int SX1278_transmit(SX1278_t * module, uint8_t * txBuf, uint8_t length,
return 0;
}
int SX1278_receive(SX1278_t * module, uint8_t length, uint32_t timeout) {
int SX1278_receive(SX1278_t *module, uint8_t length, uint32_t timeout) {
return SX1278_LoRaEntryRx(module, length, timeout);
}
uint8_t SX1278_available(SX1278_t * module) {
uint8_t SX1278_available(SX1278_t *module) {
return SX1278_LoRaRxPacket(module);
}
uint8_t SX1278_read(SX1278_t * module, uint8_t * rxBuf, uint8_t length) {
uint8_t SX1278_read(SX1278_t *module, uint8_t *rxBuf, uint8_t length) {
if (length != module->readBytes)
length = module->readBytes;
memcpy(rxBuf, module->rxBuffer, length);
@ -334,16 +277,16 @@ uint8_t SX1278_read(SX1278_t * module, uint8_t * rxBuf, uint8_t length) {
return length;
}
uint8_t SX1278_RSSI_LoRa(SX1278_t * module) {
uint8_t SX1278_RSSI_LoRa(SX1278_t *module) {
uint32_t temp = 10;
temp = SX1278_SPIRead(module, LR_RegRssiValue); //Read RegRssiValue, Rssi value
temp = temp + 127 - 137; //127:Max RSSI, 137:RSSI offset
return (uint8_t) temp;
}
uint8_t SX1278_RSSI(SX1278_t * module) {
uint8_t SX1278_RSSI(SX1278_t *module) {
uint8_t temp = 0xff;
temp = SX1278_SPIRead(module, 0x11);
temp = SX1278_SPIRead(module, RegRssiValue);
temp = 127 - (temp >> 1); //127:Max RSSI
return temp;
}

View File

@ -12,6 +12,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "SX1278_hw.h"
#define SX1278_MAX_PACKET 256
#define SX1278_DEFAULT_TIMEOUT 3000
@ -195,36 +197,24 @@ static const uint8_t SX1278_LoRaBandwidth[10] = { 0, // 7.8KHz,
#define SX1278_LORA_CR_4_7 2
#define SX1278_LORA_CR_4_8 3
static const uint8_t SX1278_CodingRate[4] = { 0x01, 0x02, 0x03, 0x04};
static const uint8_t SX1278_CodingRate[4] = { 0x01, 0x02, 0x03, 0x04 };
//CRC Enable
#define SX1278_LORA_CRC_EN 0
#define SX1278_LORA_CRC_DIS 1
static const uint8_t SX1278_CRC_Sum[2] = { 0x01, 0x00};
static const uint8_t SX1278_CRC_Sum[2] = { 0x01, 0x00 };
typedef enum _SX1278_STATUS {
SLEEP, STANDBY, TX, RX
} SX1278_Status_t;
typedef struct {
int pin;
void * port;
} SX1278_hw_dio_t;
typedef struct {
SX1278_hw_dio_t reset;
SX1278_hw_dio_t dio0;
SX1278_hw_dio_t nss;
void * spi;
} SX1278_hw_t;
typedef struct {
SX1278_hw_t * hw;
SX1278_hw_t *hw;
uint64_t frequency;
uint8_t power;
uint8_t LoRa_Rate;
uint8_t LoRa_SF;
uint8_t LoRa_BW;
uint8_t LoRa_CR;
uint8_t LoRa_CRC_sum;
@ -236,48 +226,259 @@ typedef struct {
uint8_t readBytes;
} SX1278_t;
//hardware
void SX1278_hw_init(SX1278_hw_t * hw);
void SX1278_hw_SetNSS(SX1278_hw_t * hw, int value);
void SX1278_hw_Reset(SX1278_hw_t * hw);
void SX1278_hw_SPICommand(SX1278_hw_t * hw, uint8_t cmd);
uint8_t SX1278_hw_SPIReadByte(SX1278_hw_t * hw);
void SX1278_hw_DelayMs(uint32_t msec);
int SX1278_hw_GetDIO0(SX1278_hw_t * hw);
/**
* \brief Read byte from LoRa module
*
* Reads data from LoRa module from given address.
*
* \param[in] module Pointer to LoRa structure
* \param[in] addr Address from which data will be read
*
* \return Read data
*/
uint8_t SX1278_SPIRead(SX1278_t *module, uint8_t addr);
//logic
/**
* \brief Write byte to LoRa module
*
* Writes data to LoRa module under given address.
*
* \param[in] module Pointer to LoRa structure
* \param[in] addr Address under which data will be written
* \param[in] cmd Data to write
*/
void SX1278_SPIWrite(SX1278_t *module, uint8_t addr, uint8_t cmd);
uint8_t SX1278_SPIRead(SX1278_t * module, uint8_t addr);
void SX1278_SPIWrite(SX1278_t * module, uint8_t addr, uint8_t cmd);
void SX1278_SPIBurstRead(SX1278_t * module, uint8_t addr, uint8_t * rxBuf,
/**
* \brief Read data from LoRa module
*
* Reads data from LoRa module from given address.
*
* \param[in] module Pointer to LoRa structure
* \param[in] addr Address from which data will be read
* \param[out] rxBuf Pointer to store read data
* \param[in] length Number of bytes to read
*/
void SX1278_SPIBurstRead(SX1278_t *module, uint8_t addr, uint8_t *rxBuf,
uint8_t length);
void SX1278_SPIBurstWrite(SX1278_t * module, uint8_t addr, uint8_t * txBuf,
/**
* \brief Write data to LoRa module
*
* Writes data to LoRa module under given address.
*
* \param[in] module Pointer to LoRa structure
* \param[in] addr Address under which data will be written
* \param[in] txBuf Pointer to data
* \param[in] length Number of bytes to write
*/
void SX1278_SPIBurstWrite(SX1278_t *module, uint8_t addr, uint8_t *txBuf,
uint8_t length);
void SX1278_DIO0_InterruptHandler(SX1278_t * module);
void SX1278_config(SX1278_t * module);
/**
* \brief Configure LoRa module
*
* Configure LoRa module according to parameters stored in
* module structure.
*
* \param[in] module Pointer to LoRa structure
*/
void SX1278_config(SX1278_t *module);
void SX1278_entryLoRa(SX1278_t * module);
void SX1278_clearLoRaIrq(SX1278_t * module);
int SX1278_LoRaEntryRx(SX1278_t * module, uint8_t length, uint32_t timeout);
uint8_t SX1278_LoRaRxPacket(SX1278_t * module);
int SX1278_LoRaEntryTx(SX1278_t * module, uint8_t length, uint32_t timeout);
int SX1278_LoRaTxPacket(SX1278_t * module, uint8_t * txBuf, uint8_t length,
/**
* \brief Entry LoRa mode
*
* Module supports different operation mode.
* To use LoRa operation mode one has to enter this
* particular mode to transmit and receive data
* using LoRa.
*
* \param[in] module Pointer to LoRa structure
*/
void SX1278_entryLoRa(SX1278_t *module);
/**
* \brief Clear IRQ
*
* Clears interrupt flags.
*
* \param[in] module Pointer to LoRa structure
*/
void SX1278_clearLoRaIrq(SX1278_t *module);
/**
* \brief Entry reception mode
*
* Entry reception mode
*
* \param[in] module Pointer to LoRa structure
* \param[in] length Length of message to be received
* \param[in] timeout Timeout in [ms]
*
* \return 1 if entering reception mode
* 0 if timeout was exceeded
*/
int SX1278_LoRaEntryRx(SX1278_t *module, uint8_t length, uint32_t timeout);
/**
* \brief Read data
*
* Read data and store it in module's RX buffer
*
* \param[in] module Pointer to LoRa structure
*
* \return returns number of read bytes
*/
uint8_t SX1278_LoRaRxPacket(SX1278_t *module);
/**
* \brief Entry transmitter mode
*
* Entry transmitter mode
*
* \param[in] module Pointer to LoRa structure
* \param[in] length Length of message to be sent
* \param[in] timeout Timeout in [ms]
*
* \return 1 if entering reception mode
* 0 if timeout was exceeded
*/
int SX1278_LoRaEntryTx(SX1278_t *module, uint8_t length, uint32_t timeout);
/**
* \brief Send data
*
* Transmit data
*
* \param[in] module Pointer to LoRa structure
* \param[in] txBuf Data buffer with data to be sent
* \param[in] length Length of message to be sent
* \param[in] timeout Timeout in [ms]
*
* \return 1 if entering reception mode
* 0 if timeout was exceeded
*/
int SX1278_LoRaTxPacket(SX1278_t *module, uint8_t *txBuf, uint8_t length,
uint32_t timeout);
void SX1278_init(SX1278_t * module, uint64_t frequency, uint8_t power,
uint8_t LoRa_Rate, uint8_t LoRa_BW, uint8_t LoRa_CR, uint8_t LoRa_CRC_sum, uint8_t packetLength);
/**
* \brief Initialize LoRa module
*
* Initialize LoRa module and initialize LoRa structure.
*
* \param[in] module Pointer to LoRa structure
* \param[in] frequency Frequency in [Hz]
* \param[in] power Power level, accepts SX1278_POWER_*
* \param[in] LoRa_SF LoRa spread rate, accepts SX1278_LORA_SF_*
* \param[in] LoRa_BW LoRa bandwidth, accepts SX1278_LORA_BW_*
* \param[in] LoRa_CR LoRa coding rate, accepts SX1278_LORA_CR_*
* \param[in] LoRa_CRC_sum Hardware CRC check, SX1278_LORA_CRC_EN or
* SX1278_LORA_CRC_DIS
* \param[in] packetLength Package length, no more than 256 bytes
*/
void SX1278_init(SX1278_t *module, uint64_t frequency, uint8_t power,
uint8_t LoRa_SF, uint8_t LoRa_BW, uint8_t LoRa_CR,
uint8_t LoRa_CRC_sum, uint8_t packetLength);
int SX1278_transmit(SX1278_t * module, uint8_t * txBuf, uint8_t length,
/**
* \brief Entry transmitter mode and send data
*
* Entry transmitter mode and send data.
* Combination of SX1278_LoRaEntryTx() and SX1278_LoRaTxPacket().
*
* \param[in] module Pointer to LoRa structure
* \param[in] txBuf Data buffer with data to be sent
* \param[in] length Length of message to be sent
* \param[in] timeout Timeout in [ms]
*
* \return 1 if entered TX mode and sent data
* 0 if timeout was exceeded
*/
int SX1278_transmit(SX1278_t *module, uint8_t *txBuf, uint8_t length,
uint32_t timeout);
int SX1278_(SX1278_t * module, uint8_t length, uint32_t timeoutT);
uint8_t SX1278_available(SX1278_t * module);
uint8_t SX1278_read(SX1278_t * module, uint8_t * rxBuf, uint8_t length);
uint8_t SX1278_RSSI_LoRa(SX1278_t * module);
uint8_t SX1278_RSSI(SX1278_t * module);
/**
* \brief Entry reception mode
*
* Same as SX1278_LoRaEntryRx()
*
* \param[in] module Pointer to LoRa structure
* \param[in] length Length of message to be received
* \param[in] timeout Timeout in [ms]
*
* \return 1 if entering reception mode
* 0 if timeout was exceeded
*/
int SX1278_receive(SX1278_t *module, uint8_t length, uint32_t timeout);
void SX1278_standby(SX1278_t * module);
void SX1278_sleep(SX1278_t * module);
/**
* \brief Returns number of received data
*
* Returns the number of received data which are
* held in internal buffer.
* Same as SX1278_LoRaRxPacket().
*
* \param[in] module Pointer to LoRa structure
*
* \return returns number of read bytes
*/
uint8_t SX1278_available(SX1278_t *module);
/**
* \brief Read received data to buffer
*
* Reads data from internal buffer to external
* buffer. Reads exactly number of bytes which are stored in
* internal buffer.
*
* \param[in] module Pointer to LoRa structure
* \param[out] rxBuf External buffer to store data.
* External buffer is terminated with '\0'
* character
* \param[in] length Length of message to be received
*
* \return returns number of read bytes
*/
uint8_t SX1278_read(SX1278_t *module, uint8_t *rxBuf, uint8_t length);
/**
* \brief Returns RSSI (LoRa)
*
* Returns RSSI in LoRa mode.
*
* \param[in] module Pointer to LoRa structure
*
* \return RSSI value
*/
uint8_t SX1278_RSSI_LoRa(SX1278_t *module);
/**
* \brief Returns RSSI
*
* Returns RSSI (general mode).
*
* \param[in] module Pointer to LoRa structure
*
* \return RSSI value
*/
uint8_t SX1278_RSSI(SX1278_t *module);
/**
* \brief Enter standby mode
*
* Enters standby mode.
*
* \param[in] module Pointer to LoRa structure
*/
void SX1278_standby(SX1278_t *module);
/**
* \brief Enter sleep mode
*
* Enters sleep mode.
*
* \param[in] module Pointer to LoRa structure
*/
void SX1278_sleep(SX1278_t *module);
#endif

60
driver/SX1278_hw.c Normal file
View File

@ -0,0 +1,60 @@
/**
* Author Wojciech Domski <Wojciech.Domski@gmail.com>
* www: www.Domski.pl
*
* Hardware layer for SX1278 LoRa module
*/
#include "SX1278_hw.h"
#include <string.h>
#include "gpio.h"
#include "spi.h"
__weak void SX1278_hw_init(SX1278_hw_t *hw) {
SX1278_hw_SetNSS(hw, 1);
HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_SET);
}
__weak void SX1278_hw_SetNSS(SX1278_hw_t *hw, int value) {
HAL_GPIO_WritePin(hw->nss.port, hw->nss.pin,
(value == 1) ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
__weak void SX1278_hw_Reset(SX1278_hw_t *hw) {
SX1278_hw_SetNSS(hw, 1);
HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_RESET);
SX1278_hw_DelayMs(1);
HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_SET);
SX1278_hw_DelayMs(100);
}
__weak void SX1278_hw_SPICommand(SX1278_hw_t *hw, uint8_t cmd) {
SX1278_hw_SetNSS(hw, 0);
HAL_SPI_Transmit(hw->spi, &cmd, 1, 1000);
while (HAL_SPI_GetState(hw->spi) != HAL_SPI_STATE_READY)
;
}
__weak uint8_t SX1278_hw_SPIReadByte(SX1278_hw_t *hw) {
uint8_t txByte = 0x00;
uint8_t rxByte = 0x00;
SX1278_hw_SetNSS(hw, 0);
HAL_SPI_TransmitReceive(hw->spi, &txByte, &rxByte, 1, 1000);
while (HAL_SPI_GetState(hw->spi) != HAL_SPI_STATE_READY)
;
return rxByte;
}
__weak void SX1278_hw_DelayMs(uint32_t msec) {
HAL_Delay(msec);
}
__weak int SX1278_hw_GetDIO0(SX1278_hw_t *hw) {
return (HAL_GPIO_ReadPin(hw->dio0.port, hw->dio0.pin) == GPIO_PIN_SET);
}

95
driver/SX1278_hw.h Normal file
View File

@ -0,0 +1,95 @@
/**
* Author Wojciech Domski <Wojciech.Domski@gmail.com>
* www: www.Domski.pl
*
* Hardware layer for SX1278 LoRa module
*/
#ifndef __SX1278_HW_HEADER
#define __SX1278_HW_HEADER
#include <stdint.h>
typedef struct {
int pin;
void *port;
} SX1278_hw_dio_t;
typedef struct {
SX1278_hw_dio_t reset;
SX1278_hw_dio_t dio0;
SX1278_hw_dio_t nss;
void *spi;
} SX1278_hw_t;
/**
* \brief Initialize hardware layer
*
* Clears NSS and resets LoRa module.
*
* \param[in] hw Pointer to hardware structure
*/
void SX1278_hw_init(SX1278_hw_t *hw);
/**
* \brief Control NSS
*
* Clears and sets NSS according to passed value.
*
* \param[in] hw Pointer to hardware structure.
* \param[in] value 1 sets NSS high, other value sets NSS low.
*/
void SX1278_hw_SetNSS(SX1278_hw_t *hw, int value);
/**
* \brief Resets LoRa module
*
* Resets LoRa module.
*
* \param[in] hw Pointer to hardware structure
*/
void SX1278_hw_Reset(SX1278_hw_t *hw);
/**
* \brief Send command via SPI.
*
* Send single byte via SPI interface.
*
* \param[in] hw Pointer to hardware structure
* \param[in] cmd Command
*/
void SX1278_hw_SPICommand(SX1278_hw_t *hw, uint8_t cmd);
/**
* \brief Reads data via SPI
*
* Reads data via SPI interface.
*
* \param[in] hw Pointer to hardware structure
*
* \return Read value
*/
uint8_t SX1278_hw_SPIReadByte(SX1278_hw_t *hw);
/**
* \brief ms delay
*
* Milisecond delay.
*
* \param[in] msec Number of milliseconds to wait
*/
void SX1278_hw_DelayMs(uint32_t msec);
/**
* \brief Reads DIO0 state
*
* Reads LoRa DIO0 state using GPIO.
*
* \param[in] hw Pointer to hardware structure
*
* \return 0 if DIO0 low, 1 if DIO high
*/
int SX1278_hw_GetDIO0(SX1278_hw_t *hw);
#endif