Line data Source code
1 : #include "LR1110.h"
2 : #include <math.h>
3 :
4 : #if !RADIOLIB_EXCLUDE_LR11X0
5 :
6 1 : LR1110::LR1110(Module* mod) : LR11x0(mod) {
7 1 : chipType = RADIOLIB_LR11X0_DEVICE_LR1110;
8 1 : }
9 :
10 0 : int16_t LR1110::begin(const ConfigLoRa_t& cfg) {
11 : // execute common part
12 0 : int16_t state = LR11x0::begin(cfg.bandwidth, cfg.spreadingFactor, cfg.codingRate, cfg.syncWord, cfg.preambleLength);
13 0 : RADIOLIB_ASSERT(state);
14 :
15 : // configure publicly accessible settings
16 0 : state = setFrequency(cfg.frequency);
17 0 : RADIOLIB_ASSERT(state);
18 :
19 0 : state = setOutputPower(cfg.power);
20 0 : return(state);
21 : }
22 :
23 0 : int16_t LR1110::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
24 0 : ConfigLoRa_t cfg;
25 0 : cfg.frequency = freq;
26 0 : cfg.bandwidth = bw;
27 0 : cfg.spreadingFactor = sf;
28 0 : cfg.codingRate = cr;
29 0 : cfg.syncWord = syncWord;
30 0 : cfg.power = power;
31 0 : cfg.preambleLength = preambleLength;
32 0 : this->tcxoVoltage = tcxoVoltage;
33 0 : return(begin(cfg));
34 : }
35 :
36 0 : int16_t LR1110::beginGFSK(const ConfigFSK_t& cfg) {
37 : // execute common part
38 0 : int16_t state = LR11x0::beginGFSK(cfg.bitRate, cfg.frequencyDeviation, cfg.receiverBandwidth, cfg.preambleLength);
39 0 : RADIOLIB_ASSERT(state);
40 :
41 : // configure publicly accessible settings
42 0 : state = setFrequency(cfg.frequency);
43 0 : RADIOLIB_ASSERT(state);
44 :
45 0 : state = setOutputPower(cfg.power);
46 0 : return(state);
47 : }
48 :
49 0 : int16_t LR1110::beginGFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
50 0 : ConfigFSK_t cfg;
51 0 : cfg.frequency = freq;
52 0 : cfg.bitRate = br;
53 0 : cfg.frequencyDeviation = freqDev;
54 0 : cfg.receiverBandwidth = rxBw;
55 0 : cfg.power = power;
56 0 : cfg.preambleLength = preambleLength;
57 0 : this->tcxoVoltage = tcxoVoltage;
58 0 : return(beginGFSK(cfg));
59 : }
60 :
61 0 : int16_t LR1110::beginLRFHSS(const ConfigLRFHSS_t& cfg) {
62 : // execute common part
63 0 : int16_t state = LR11x0::beginLRFHSS(cfg.bandwidth, cfg.bandwidth, cfg.narrowGrid);
64 0 : RADIOLIB_ASSERT(state);
65 :
66 : // configure publicly accessible settings
67 0 : state = setFrequency(cfg.frequency);
68 0 : RADIOLIB_ASSERT(state);
69 :
70 0 : state = setOutputPower(cfg.power);
71 0 : return(state);
72 : }
73 :
74 0 : int16_t LR1110::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, bool narrowGrid, int8_t power, float tcxoVoltage) {
75 0 : ConfigLRFHSS_t cfg;
76 0 : cfg.frequency = freq;
77 0 : cfg.bandwidth = bw;
78 0 : cfg.codingRate = cr;
79 0 : cfg.narrowGrid = narrowGrid;
80 0 : cfg.power = power;
81 0 : this->tcxoVoltage = tcxoVoltage;
82 0 : return(beginLRFHSS(cfg));
83 : }
84 :
85 1 : int16_t LR1110::setFrequency(float freq) {
86 1 : return(this->setFrequency(freq, false));
87 : }
88 :
89 1 : int16_t LR1110::setFrequency(float freq, bool skipCalibration, float band) {
90 1 : RADIOLIB_CHECK_RANGE(freq, 150.0f, 960.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
91 :
92 : // check if we need to recalibrate image
93 : int16_t state;
94 0 : if(!skipCalibration && (fabsf(freq - this->freqMHz) >= RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ)) {
95 0 : state = LR11x0::calibrateImageRejection(freq - band, freq + band);
96 0 : RADIOLIB_ASSERT(state);
97 : }
98 :
99 : // set frequency
100 0 : state = LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f));
101 0 : RADIOLIB_ASSERT(state);
102 0 : this->freqMHz = freq;
103 0 : return(state);
104 : }
105 :
106 1 : int16_t LR1110::setOutputPower(int8_t power) {
107 1 : return(this->setOutputPower(power, false));
108 : }
109 :
110 1 : int16_t LR1110::setOutputPower(int8_t power, bool forceHighPower, uint32_t rampTimeUs) {
111 : // check if power value is configurable
112 1 : int16_t state = this->checkOutputPower(power, NULL, forceHighPower);
113 1 : RADIOLIB_ASSERT(state);
114 :
115 : // determine whether to use HP or LP PA and check range accordingly
116 1 : bool useHp = forceHighPower || (power > 14);
117 1 : this->txMode = useHp ? LR11x0::MODE_TX_HP : LR11x0::MODE_TX;
118 :
119 : // TODO how and when to configure OCP?
120 :
121 : // update PA config and set output power - always use VBAT for high-power PA
122 : // the value returned by LRxxxx class is offset by 3 for LR11x0
123 1 : state = LR11x0::setOutputPower(power, (uint8_t)useHp, (uint8_t)useHp, 0x04, 0x07, roundRampTime(rampTimeUs) - 0x03);
124 1 : return(state);
125 : }
126 :
127 1 : int16_t LR1110::checkOutputPower(int8_t power, int8_t* clipped) {
128 1 : return(checkOutputPower(power, clipped, false));
129 : }
130 :
131 2 : int16_t LR1110::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower) {
132 2 : if(forceHighPower || (power > 14)) {
133 0 : if(clipped) {
134 0 : *clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
135 : }
136 0 : RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
137 :
138 : } else {
139 2 : if(clipped) {
140 0 : *clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
141 : }
142 2 : RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
143 :
144 : }
145 2 : return(RADIOLIB_ERR_NONE);
146 : }
147 :
148 1 : int16_t LR1110::setModem(ModemType_t modem) {
149 1 : switch(modem) {
150 0 : case(ModemType_t::RADIOLIB_MODEM_LORA): {
151 0 : return(this->begin());
152 : } break;
153 0 : case(ModemType_t::RADIOLIB_MODEM_FSK): {
154 0 : return(this->beginGFSK());
155 : } break;
156 0 : case(ModemType_t::RADIOLIB_MODEM_LRFHSS): {
157 0 : return(this->beginLRFHSS());
158 : } break;
159 1 : default:
160 1 : return(RADIOLIB_ERR_WRONG_MODEM);
161 : }
162 : return(RADIOLIB_ERR_WRONG_MODEM);
163 : }
164 :
165 : #endif
|