From 7e6b98f77b5d769462caed8aac458ad29ced497d Mon Sep 17 00:00:00 2001 From: Wojciech Domski Date: Sat, 28 Oct 2017 11:27:06 +0200 Subject: [PATCH] Initial release. --- driver/SX1278.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++++ driver/SX1278.h | 299 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 643 insertions(+) create mode 100644 driver/SX1278.c create mode 100644 driver/SX1278.h diff --git a/driver/SX1278.c b/driver/SX1278.c new file mode 100644 index 0000000..a18e0ba --- /dev/null +++ b/driver/SX1278.c @@ -0,0 +1,344 @@ +/** + * Author Wojciech Domski + * www: www.Domski.pl + * + * work based on DORJI.COM sample code and + * https://github.com/realspinner/SX1278_LoRa + */ + +#include "SX1278.h" +#include + +#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 tmp; + SX1278_hw_SPICommand(module->hw, addr); + tmp = SX1278_hw_SPIReadByte(module->hw); + SX1278_hw_SetNSS(module->hw, 1); + return tmp; +} + +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, + uint8_t length) { + uint8_t i; + if (length <= 1) { + return; + } else { + SX1278_hw_SetNSS(module->hw, 0); + SX1278_hw_SPICommand(module->hw, addr); + for (i = 0; i < length; i++) { + *(rxBuf + i) = SX1278_hw_SPIReadByte(module->hw); + } + SX1278_hw_SetNSS(module->hw, 1); + } +} + +void SX1278_SPIBurstWrite(SX1278_t * module, uint8_t addr, uint8_t* txBuf, + uint8_t length) { + unsigned char i; + if (length <= 1) { + return; + } else { + SX1278_hw_SetNSS(module->hw, 0); + SX1278_hw_SPICommand(module->hw, addr | 0x80); + for (i = 0; i < length; i++) { + SX1278_hw_SPICommand(module->hw, *(txBuf + i)); + } + SX1278_hw_SetNSS(module->hw, 1); + } +} + +void SX1278_defaultConfig(SX1278_t * module) { + SX1278_config(module, module->frequency, module->power, module->LoRa_Rate, + module->LoRa_BW); +} + +void SX1278_config(SX1278_t * module, uint8_t frequency, uint8_t power, + uint8_t LoRa_Rate, uint8_t LoRa_BW) { + SX1278_sleep(module); //Change modem mode Must in Sleep mode + SX1278_hw_DelayMs(15); + + SX1278_entryLoRa(module); + //SX1278_SPIWrite(module, 0x5904); //?? Change digital regulator form 1.6V to 1.47V: see errata note + + SX1278_SPIBurstWrite(module, LR_RegFrMsb, + (uint8_t*) SX1278_Frequency[frequency], 3); //setting frequency parameter + + //setting base parameter + SX1278_SPIWrite(module, LR_RegPaConfig, SX1278_Power[power]); //Setting output power parameter + + SX1278_SPIWrite(module, LR_RegOcp, 0x0B); //RegOcp,Close Ocp + SX1278_SPIWrite(module, LR_RegLna, 0x23); //RegLNA,High & LNA Enable + if (SX1278_SpreadFactor[LoRa_Rate] == 6) { //SFactor=6 + uint8_t tmp; + SX1278_SPIWrite(module, + LR_RegModemConfig1, + ((SX1278_LoRaBandwidth[LoRa_BW] << 4) + (SX1278_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[LoRa_Rate] << 4) + (SX1278_CRC << 2) + + 0x03)); + + tmp = SX1278_SPIRead(module, 0x31); + tmp &= 0xF8; + tmp |= 0x05; + SX1278_SPIWrite(module, 0x31, tmp); + SX1278_SPIWrite(module, 0x37, 0x0C); + } else { + SX1278_SPIWrite(module, + LR_RegModemConfig1, + ((SX1278_LoRaBandwidth[LoRa_BW] << 4) + (SX1278_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[LoRa_Rate] << 4) + (SX1278_CRC << 2) + + 0x03)); //SFactor & LNA gain set by the internal AGC loop + } + + SX1278_SPIWrite(module, LR_RegSymbTimeoutLsb, 0xFF); //RegSymbTimeoutLsb Timeout = 0x3FF(Max) + SX1278_SPIWrite(module, LR_RegPreambleMsb, 0x00); //RegPreambleMsb + SX1278_SPIWrite(module, LR_RegPreambleLsb, 12); //RegPreambleLsb 8+4=12byte Preamble + SX1278_SPIWrite(module, REG_LR_DIOMAPPING2, 0x01); //RegDioMapping2 DIO5=00, DIO4=01 + module->readBytes = 0; + SX1278_standby(module); //Entry standby mode +} + +void SX1278_standby(SX1278_t * module) { + SX1278_SPIWrite(module, LR_RegOpMode, 0x09); + module->status = STANDBY; +} + +void SX1278_sleep(SX1278_t * module) { + SX1278_SPIWrite(module, LR_RegOpMode, 0x08); + module->status = SLEEP; +} + +void SX1278_entryLoRa(SX1278_t * module) { + SX1278_SPIWrite(module, LR_RegOpMode, 0x88); +} + +void SX1278_clearLoRaIrq(SX1278_t * module) { + SX1278_SPIWrite(module, LR_RegIrqFlags, 0xFF); +} + +int SX1278_LoRaEntryRx(SX1278_t * module, uint8_t length, uint32_t timeout) { + uint8_t addr; + + module->packetLength = length; + + SX1278_defaultConfig(module); //Setting base parameter + SX1278_SPIWrite(module, REG_LR_PADAC, 0x84); //Normal and RX + SX1278_SPIWrite(module, LR_RegHopPeriod, 0xFF); //No FHSS + SX1278_SPIWrite(module, REG_LR_DIOMAPPING1, 0x01);//DIO=00,DIO1=00,DIO2=00, DIO3=01 + SX1278_SPIWrite(module, LR_RegIrqFlagsMask, 0x3F);//Open RxDone interrupt & Timeout + SX1278_clearLoRaIrq(module); + SX1278_SPIWrite(module, LR_RegPayloadLength, length);//Payload Length 21byte(this register must difine when the data long of one byte in SF is 6) + addr = SX1278_SPIRead(module, LR_RegFifoRxBaseAddr); //Read RxBaseAddr + SX1278_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RxBaseAddr->FiFoAddrPtr + SX1278_SPIWrite(module, LR_RegOpMode, 0x8d); //Mode//Low Frequency Mode + //SX1278_SPIWrite(module, LR_RegOpMode,0x05); //Continuous Rx Mode //High Frequency Mode + module->readBytes = 0; + + while (1) { + if ((SX1278_SPIRead(module, LR_RegModemStat) & 0x04) == 0x04) { //Rx-on going RegModemStat + module->status = RX; + return 1; + } + if (--timeout == 0) { + SX1278_hw_Reset(module->hw); + SX1278_defaultConfig(module); + return 0; + } + SX1278_hw_DelayMs(1); + } +} + +uint8_t SX1278_LoRaRxPacket(SX1278_t * module) { + unsigned char addr; + unsigned char packet_size; + + if (SX1278_hw_GetDIO0(module->hw)) { + memset(module->rxBuffer, 0x00, SX1278_MAX_PACKET); + + 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) + packet_size = module->packetLength; + } else { + packet_size = SX1278_SPIRead(module, LR_RegRxNbBytes); //Number for received bytes + } + + SX1278_SPIBurstRead(module, 0x00, module->rxBuffer, packet_size); + module->readBytes = packet_size; + SX1278_clearLoRaIrq(module); + } + return module->readBytes; +} + +int SX1278_LoRaEntryTx(SX1278_t * module, uint8_t length, uint32_t timeout) { + uint8_t addr; + uint8_t temp; + + module->packetLength = length; + + SX1278_defaultConfig(module); //setting base parameter + SX1278_SPIWrite(module, REG_LR_PADAC, 0x87); //Tx for 20dBm + SX1278_SPIWrite(module, LR_RegHopPeriod, 0x00); //RegHopPeriod NO FHSS + SX1278_SPIWrite(module, REG_LR_DIOMAPPING1, 0x41); //DIO0=01, DIO1=00,DIO2=00, DIO3=01 + SX1278_clearLoRaIrq(module); + SX1278_SPIWrite(module, LR_RegIrqFlagsMask, 0xF7); //Open TxDone interrupt + SX1278_SPIWrite(module, LR_RegPayloadLength, length); //RegPayloadLength 21byte + addr = SX1278_SPIRead(module, LR_RegFifoTxBaseAddr); //RegFiFoTxBaseAddr + SX1278_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RegFifoAddrPtr + + while (1) { + temp = SX1278_SPIRead(module, LR_RegPayloadLength); + if (temp == length) { + module->status = TX; + return 1; + } + + if (--timeout == 0) { + SX1278_hw_Reset(module->hw); + SX1278_defaultConfig(module); + return 0; + } + } +} + +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 + while (1) { + if (SX1278_hw_GetDIO0(module->hw)) { //if(Get_NIRQ()) //Packet send over + SX1278_SPIRead(module, LR_RegIrqFlags); + SX1278_clearLoRaIrq(module); //Clear irq + SX1278_standby(module); //Entry Standby mode + return 1; + } + + if (--timeout == 0) { + SX1278_hw_Reset(module->hw); + SX1278_defaultConfig(module); + return 0; + } + SX1278_hw_DelayMs(1); + } +} + +void SX1278_begin(SX1278_t * module, uint8_t frequency, uint8_t power, + uint8_t LoRa_Rate, uint8_t LoRa_BW, uint8_t packetLength) { + SX1278_hw_init(module->hw); + module->frequency = frequency; + module->power = power; + module->LoRa_Rate = LoRa_Rate; + module->LoRa_BW = LoRa_BW; + module->packetLength = packetLength; + SX1278_defaultConfig(module); +} + +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); + } + return 0; +} + +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) { + return SX1278_LoRaRxPacket(module); +} + +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); + rxBuf[length] = '\0'; + module->readBytes = 0; + return length; +} + +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 temp = 0xff; + temp = SX1278_SPIRead(module, 0x11); + temp = 127 - (temp >> 1); //127:Max RSSI + return temp; +} diff --git a/driver/SX1278.h b/driver/SX1278.h new file mode 100644 index 0000000..f481add --- /dev/null +++ b/driver/SX1278.h @@ -0,0 +1,299 @@ +/** + * Author Wojciech Domski + * www: www.Domski.pl + * + * work based on DORJI.COM sample code and + * https://github.com/realspinner/SX1278_LoRa + */ + +#ifndef __SX1278_H__ +#define __SX1278_H__ + +#include +#include + +#define SX1278_MAX_PACKET 256 +#define SX1278_DEFAULT_TIMEOUT 3000 + +//Error Coding rate (CR)setting +#define SX1278_CR_4_5 +//#define SX1278_CR_4_6 +//#define SX1278_CR_4_7 +//#define SX1278_CR_4_8 +#ifdef SX1278_CR_4_5 +#define SX1278_CR 0x01 +#else +#ifdef SX1278_CR_4_6 +#define SX1278_CR 0x02 +#else +#ifdef SX1278_CR_4_7 +#define SX1278_CR 0x03 +#else +#ifdef SX1278_CR_4_8 +#define SX1278_CR 0x04 +#endif +#endif +#endif +#endif + +//CRC Enable +#define SX1278_CRC_EN +#ifdef SX1278_CRC_EN +#define SX1278_CRC 0x01 +#else +#define SX1278_CRC 0x00 +#endif +//RFM98 Internal registers Address +/********************LoRa mode***************************/ +#define LR_RegFifo 0x00 +// Common settings +#define LR_RegOpMode 0x01 +#define LR_RegFrMsb 0x06 +#define LR_RegFrMid 0x07 +#define LR_RegFrLsb 0x08 +// Tx settings +#define LR_RegPaConfig 0x09 +#define LR_RegPaRamp 0x0A +#define LR_RegOcp 0x0B +// Rx settings +#define LR_RegLna 0x0C +// LoRa registers +#define LR_RegFifoAddrPtr 0x0D +#define LR_RegFifoTxBaseAddr 0x0E +#define LR_RegFifoRxBaseAddr 0x0F +#define LR_RegFifoRxCurrentaddr 0x10 +#define LR_RegIrqFlagsMask 0x11 +#define LR_RegIrqFlags 0x12 +#define LR_RegRxNbBytes 0x13 +#define LR_RegRxHeaderCntValueMsb 0x14 +#define LR_RegRxHeaderCntValueLsb 0x15 +#define LR_RegRxPacketCntValueMsb 0x16 +#define LR_RegRxPacketCntValueLsb 0x17 +#define LR_RegModemStat 0x18 +#define LR_RegPktSnrValue 0x19 +#define LR_RegPktRssiValue 0x1A +#define LR_RegRssiValue 0x1B +#define LR_RegHopChannel 0x1C +#define LR_RegModemConfig1 0x1D +#define LR_RegModemConfig2 0x1E +#define LR_RegSymbTimeoutLsb 0x1F +#define LR_RegPreambleMsb 0x20 +#define LR_RegPreambleLsb 0x21 +#define LR_RegPayloadLength 0x22 +#define LR_RegMaxPayloadLength 0x23 +#define LR_RegHopPeriod 0x24 +#define LR_RegFifoRxByteAddr 0x25 +// I/O settings +#define REG_LR_DIOMAPPING1 0x40 +#define REG_LR_DIOMAPPING2 0x41 +// Version +#define REG_LR_VERSION 0x42 +// Additional settings +#define REG_LR_PLLHOP 0x44 +#define REG_LR_TCXO 0x4B +#define REG_LR_PADAC 0x4D +#define REG_LR_FORMERTEMP 0x5B +#define REG_LR_AGCREF 0x61 +#define REG_LR_AGCTHRESH1 0x62 +#define REG_LR_AGCTHRESH2 0x63 +#define REG_LR_AGCTHRESH3 0x64 + +/********************FSK/ook mode***************************/ +#define RegFIFO 0x00 +#define RegOpMode 0x01 +#define RegBitRateMsb 0x02 +#define RegBitRateLsb 0x03 +#define RegFdevMsb 0x04 +#define RegFdevLsb 0x05 +#define RegFreqMsb 0x06 +#define RegFreqMid 0x07 +#define RegFreqLsb 0x08 +#define RegPaConfig 0x09 +#define RegPaRamp 0x0a +#define RegOcp 0x0b +#define RegLna 0x0c +#define RegRxConfig 0x0d +#define RegRssiConfig 0x0e +#define RegRssiCollision 0x0f +#define RegRssiThresh 0x10 +#define RegRssiValue 0x11 +#define RegRxBw 0x12 +#define RegAfcBw 0x13 +#define RegOokPeak 0x14 +#define RegOokFix 0x15 +#define RegOokAvg 0x16 +#define RegAfcFei 0x1a +#define RegAfcMsb 0x1b +#define RegAfcLsb 0x1c +#define RegFeiMsb 0x1d +#define RegFeiLsb 0x1e +#define RegPreambleDetect 0x1f +#define RegRxTimeout1 0x20 +#define RegRxTimeout2 0x21 +#define RegRxTimeout3 0x22 +#define RegRxDelay 0x23 +#define RegOsc 0x24 +#define RegPreambleMsb 0x25 +#define RegPreambleLsb 0x26 +#define RegSyncConfig 0x27 +#define RegSyncValue1 0x28 +#define RegSyncValue2 0x29 +#define RegSyncValue3 0x2a +#define RegSyncValue4 0x2b +#define RegSyncValue5 0x2c +#define RegSyncValue6 0x2d +#define RegSyncValue7 0x2e +#define RegSyncValue8 0x2f +#define RegPacketConfig1 0x30 +#define RegPacketConfig2 0x31 +#define RegPayloadLength 0x32 +#define RegNodeAdrs 0x33 +#define RegBroadcastAdrs 0x34 +#define RegFifoThresh 0x35 +#define RegSeqConfig1 0x36 +#define RegSeqConfig2 0x37 +#define RegTimerResol 0x38 +#define RegTimer1Coef 0x39 +#define RegTimer2Coef 0x3a +#define RegImageCal 0x3b +#define RegTemp 0x3c +#define RegLowBat 0x3d +#define RegIrqFlags1 0x3e +#define RegIrqFlags2 0x3f +#define RegDioMapping1 0x40 +#define RegDioMapping2 0x41 +#define RegVersion 0x42 +#define RegPllHop 0x44 +#define RegPaDac 0x4d +#define RegBitRateFrac 0x5d + +/********************************************************** + **Parameter table define + **********************************************************/ +#define SX1278_433MHZ 0 + +static const uint8_t SX1278_Frequency[1][3] = { { 0x6C, 0x80, 0x00 }, //434MHz + }; + +#define SX1278_POWER_20DBM 0 +#define SX1278_POWER_17DBM 1 +#define SX1278_POWER_14DBM 2 +#define SX1278_POWER_11DBM 3 + +static const uint8_t SX1278_Power[4] = { 0xFF, //20dbm + 0xFC, //17dbm + 0xF9, //14dbm + 0xF6, //11dbm + }; + +#define SX1278_LORA_SF_6 0 +#define SX1278_LORA_SF_7 1 +#define SX1278_LORA_SF_8 2 +#define SX1278_LORA_SF_9 3 +#define SX1278_LORA_SF_10 4 +#define SX1278_LORA_SF_11 5 +#define SX1278_LORA_SF_12 6 + +static const uint8_t SX1278_SpreadFactor[7] = { 6, 7, 8, 9, 10, 11, 12 }; + +#define SX1278_LORA_BW_7_8KHZ 0 +#define SX1278_LORA_BW_10_4KHZ 1 +#define SX1278_LORA_BW_15_6KHZ 2 +#define SX1278_LORA_BW_20_8KHZ 3 +#define SX1278_LORA_BW_31_2KHZ 4 +#define SX1278_LORA_BW_41_7KHZ 5 +#define SX1278_LORA_BW_62_5KHZ 6 +#define SX1278_LORA_BW_125KHZ 7 +#define SX1278_LORA_BW_250KHZ 8 +#define SX1278_LORA_BW_500KHZ 9 + +static const uint8_t SX1278_LoRaBandwidth[10] = { 0, // 7.8KHz, + 1, // 10.4KHz, + 2, // 15.6KHz, + 3, // 20.8KHz, + 4, // 31.2KHz, + 5, // 41.7KHz, + 6, // 62.5KHz, + 7, // 125.0KHz, + 8, // 250.0KHz, + 9 // 500.0KHz + }; + +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; + + uint8_t frequency; + uint8_t power; + uint8_t LoRa_Rate; + uint8_t LoRa_BW; + uint8_t packetLength; + + SX1278_Status_t status; + + uint8_t rxBuffer[SX1278_MAX_PACKET]; + uint8_t readBytes; +} SX1278_t; + +//hardware +__weak void SX1278_hw_init(SX1278_hw_t * hw); +__weak void SX1278_hw_SetNSS(SX1278_hw_t * hw, int value); +__weak void SX1278_hw_Reset(SX1278_hw_t * hw); +__weak void SX1278_hw_SPICommand(SX1278_hw_t * hw, uint8_t cmd); +__weak uint8_t SX1278_hw_SPIReadByte(SX1278_hw_t * hw); +__weak void SX1278_hw_DelayMs(uint32_t msec); +__weak int SX1278_hw_GetDIO0(SX1278_hw_t * hw); + +//logic + +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, + uint8_t length); +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, uint8_t frequency, uint8_t power, + uint8_t LoRa_Rate, uint8_t LoRa_BW); +void SX1278_defaultConfig(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, + uint32_t timeout); + +void SX1278_begin(SX1278_t * module, uint8_t frequency, uint8_t power, + uint8_t LoRa_Rate, uint8_t LoRa_BW, uint8_t packetLength); + +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); + +void SX1278_standby(SX1278_t * module); +void SX1278_sleep(SX1278_t * module); + +#endif