Line data Source code
1 : #include "SX1277.h"
2 : #if !RADIOLIB_EXCLUDE_SX127X
3 :
4 1 : SX1277::SX1277(Module* mod) : SX1278(mod) {
5 :
6 1 : }
7 :
8 0 : int16_t SX1277::begin(const ConfigLoRa_t& cfg) {
9 : // execute common part
10 0 : const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
11 0 : int16_t state = SX127x::begin(versions, 3, cfg.syncWord, cfg.preambleLength);
12 0 : RADIOLIB_ASSERT(state);
13 :
14 : // configure publicly accessible settings
15 0 : state = setBandwidth(cfg.bandwidth);
16 0 : RADIOLIB_ASSERT(state);
17 :
18 0 : state = setFrequency(cfg.frequency);
19 0 : RADIOLIB_ASSERT(state);
20 :
21 0 : state = setSpreadingFactor(cfg.spreadingFactor);
22 0 : RADIOLIB_ASSERT(state);
23 :
24 0 : state = setCodingRate(cfg.codingRate);
25 0 : RADIOLIB_ASSERT(state);
26 :
27 0 : state = setOutputPower(cfg.power);
28 0 : RADIOLIB_ASSERT(state);
29 :
30 0 : state = setGain(this->gain);
31 0 : RADIOLIB_ASSERT(state);
32 :
33 : // set publicly accessible settings that are not a part of begin method
34 0 : state = setCRC(true);
35 0 : return(state);
36 : }
37 :
38 0 : int16_t SX1277::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) {
39 0 : ConfigLoRa_t cfg;
40 0 : cfg.frequency = freq;
41 0 : cfg.bandwidth = bw;
42 0 : cfg.spreadingFactor = sf;
43 0 : cfg.codingRate = cr;
44 0 : cfg.syncWord = syncWord;
45 0 : cfg.power = power;
46 0 : cfg.preambleLength = preambleLength;
47 0 : this->gain = gain;
48 0 : return(begin(cfg));
49 : }
50 :
51 0 : int16_t SX1277::beginFSK(const ConfigFSK_t& cfg) {
52 : // execute common part
53 0 : const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
54 0 : int16_t state = SX127x::beginFSK(versions, 3, cfg.frequencyDeviation, cfg.receiverBandwidth, cfg.preambleLength);
55 0 : RADIOLIB_ASSERT(state);
56 :
57 : // configure settings not accessible by API
58 0 : state = configFSK();
59 0 : RADIOLIB_ASSERT(state);
60 :
61 : // configure publicly accessible settings
62 0 : state = setFrequency(cfg.frequency);
63 0 : RADIOLIB_ASSERT(state);
64 :
65 0 : state = setBitRate(cfg.bitRate);
66 0 : RADIOLIB_ASSERT(state);
67 :
68 0 : state = setOutputPower(cfg.power);
69 0 : RADIOLIB_ASSERT(state);
70 :
71 0 : if(this->enableOOK) {
72 0 : state = setDataShapingOOK(RADIOLIB_SHAPING_NONE);
73 0 : RADIOLIB_ASSERT(state);
74 : } else {
75 0 : state = setDataShaping(RADIOLIB_SHAPING_NONE);
76 0 : RADIOLIB_ASSERT(state);
77 : }
78 :
79 : // set publicly accessible settings that are not a part of begin method
80 0 : state = setCRC(true);
81 0 : return(state);
82 : }
83 :
84 0 : int16_t SX1277::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
85 0 : ConfigFSK_t cfg;
86 0 : cfg.frequency = freq;
87 0 : cfg.bitRate = br;
88 0 : cfg.frequencyDeviation = freqDev;
89 0 : cfg.receiverBandwidth = rxBw;
90 0 : cfg.power = power;
91 0 : cfg.preambleLength = preambleLength;
92 0 : this->enableOOK = enableOOK;
93 0 : return(beginFSK(cfg));
94 : }
95 :
96 1 : int16_t SX1277::setFrequency(float freq) {
97 : // NOTE: The datasheet specifies Band 2 as 410-525 MHz, but the hardware has been
98 : // verified to work down to ~395 MHz. The lower bound is set here to 395 MHz to
99 : // accommodate real-world use cases (e.g. TinyGS satellites, radiosondes) while
100 : // adding a small margin below the 400 MHz practical limit.
101 1 : if(!(((freq >= 137.0f) && (freq <= 175.0f)) ||
102 1 : ((freq >= 395.0f) && (freq <= 525.0f)) ||
103 1 : ((freq >= 862.0f) && (freq <= 1020.0f)))) {
104 1 : return(RADIOLIB_ERR_INVALID_FREQUENCY);
105 : }
106 :
107 : // set frequency and if successful, save the new setting
108 0 : int16_t state = SX127x::setFrequencyRaw(freq);
109 0 : if(state == RADIOLIB_ERR_NONE) {
110 0 : SX127x::frequency = freq;
111 : }
112 0 : return(state);
113 : }
114 :
115 1 : int16_t SX1277::setSpreadingFactor(uint8_t sf) {
116 : uint8_t newSpreadingFactor;
117 :
118 : // check allowed spreading factor values
119 1 : switch(sf) {
120 0 : case 6:
121 0 : newSpreadingFactor = RADIOLIB_SX127X_SF_6;
122 0 : break;
123 0 : case 7:
124 0 : newSpreadingFactor = RADIOLIB_SX127X_SF_7;
125 0 : break;
126 0 : case 8:
127 0 : newSpreadingFactor = RADIOLIB_SX127X_SF_8;
128 0 : break;
129 0 : case 9:
130 0 : newSpreadingFactor = RADIOLIB_SX127X_SF_9;
131 0 : break;
132 1 : default:
133 1 : return(RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
134 : }
135 :
136 : // set spreading factor and if successful, save the new setting
137 0 : int16_t state = SX1278::setSpreadingFactorRaw(newSpreadingFactor);
138 0 : if(state == RADIOLIB_ERR_NONE) {
139 0 : SX127x::spreadingFactor = sf;
140 : }
141 :
142 0 : return(state);
143 : }
144 :
145 1 : int16_t SX1277::setDataRate(DataRate_t dr, ModemType_t modem) {
146 : // get the current modem
147 : ModemType_t currentModem;
148 1 : int16_t state = this->getModem(¤tModem);
149 1 : RADIOLIB_ASSERT(state);
150 :
151 : // switch over if the requested modem is different
152 1 : if(modem != RADIOLIB_MODEM_NONE && modem != currentModem) {
153 0 : state = this->standby();
154 0 : RADIOLIB_ASSERT(state);
155 0 : state = this->setModem(modem);
156 0 : RADIOLIB_ASSERT(state);
157 : }
158 :
159 1 : if(modem == RADIOLIB_MODEM_NONE) {
160 1 : modem = currentModem;
161 : }
162 :
163 : // select interpretation based on modem
164 1 : if(modem == RADIOLIB_MODEM_FSK) {
165 : // set the bit rate
166 0 : state = this->setBitRate(dr.fsk.bitRate);
167 0 : RADIOLIB_ASSERT(state);
168 :
169 : // set the frequency deviation
170 0 : state = this->setFrequencyDeviation(dr.fsk.freqDev);
171 :
172 1 : } else if(modem == RADIOLIB_MODEM_LORA) {
173 : // set the spreading factor
174 1 : state = this->setSpreadingFactor(dr.lora.spreadingFactor);
175 1 : RADIOLIB_ASSERT(state);
176 :
177 : // set the bandwidth
178 0 : state = this->setBandwidth(dr.lora.bandwidth);
179 : }
180 :
181 0 : return(state);
182 : }
183 :
184 1 : int16_t SX1277::checkDataRate(DataRate_t dr, ModemType_t modem) {
185 1 : int16_t state = RADIOLIB_ERR_UNKNOWN;
186 :
187 : // retrieve modem if not supplied
188 1 : if(modem == RADIOLIB_MODEM_NONE) {
189 1 : state = this->getModem(&modem);
190 1 : RADIOLIB_ASSERT(state);
191 : }
192 :
193 : // select interpretation based on modem
194 1 : if(modem == RADIOLIB_MODEM_FSK) {
195 0 : RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
196 0 : if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0f <= 250.0f) && (dr.fsk.freqDev <= 200.0f))) {
197 0 : return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
198 : }
199 0 : return(RADIOLIB_ERR_NONE);
200 :
201 1 : } else if(modem == RADIOLIB_MODEM_LORA) {
202 1 : RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 6, 9, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
203 0 : RADIOLIB_CHECK_RANGE(dr.lora.bandwidth, 0.0f, 510.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
204 0 : RADIOLIB_CHECK_RANGE(dr.lora.codingRate, 4, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
205 0 : return(RADIOLIB_ERR_NONE);
206 :
207 : }
208 :
209 0 : return(state);
210 : }
211 :
212 1 : int16_t SX1277::setModem(ModemType_t modem) {
213 1 : switch(modem) {
214 0 : case(ModemType_t::RADIOLIB_MODEM_LORA): {
215 0 : return(this->begin());
216 : } break;
217 0 : case(ModemType_t::RADIOLIB_MODEM_FSK): {
218 0 : return(this->beginFSK());
219 : } break;
220 1 : default:
221 1 : return(RADIOLIB_ERR_WRONG_MODEM);
222 : }
223 : }
224 :
225 : #endif
|