Silence unused-variable warning (#2872)
[ExpressLRS.git] / src / lib / SX1280Driver / SX1280_hal.cpp
bloba5949f2bc8db20cd8ff77c9a79b97df9c7dff063
1 /*
2 ______ _
3 / _____) _ | |
4 ( (____ _____ ____ _| |_ _____ ____| |__
5 \____ \| ___ | (_ _) ___ |/ ___) _ \
6 _____) ) ____| | | || |_| ____( (___| | | |
7 (______/|_____)_|_|_| \__)_____)\____)_| |_|
8 (C)2016 Semtech
10 Description: Handling of the node configuration protocol
12 License: Revised BSD License, see LICENSE.TXT file include in the project
14 Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy
16 Modified and adapted by Alessandro Carcione for ELRS project
19 #ifndef UNIT_TEST
20 #include "SX1280_Regs.h"
21 #include "SX1280_hal.h"
22 #include <SPIEx.h>
23 #include "logging.h"
25 SX1280Hal *SX1280Hal::instance = NULL;
27 SX1280Hal::SX1280Hal()
29 instance = this;
32 void SX1280Hal::end()
34 detachInterrupt(GPIO_PIN_DIO1);
35 if (GPIO_PIN_DIO1_2 != UNDEF_PIN)
37 detachInterrupt(GPIO_PIN_DIO1_2);
39 SPIEx.end();
40 IsrCallback_1 = nullptr; // remove callbacks
41 IsrCallback_2 = nullptr; // remove callbacks
44 void SX1280Hal::init()
46 DBGLN("Hal Init");
48 if (GPIO_PIN_BUSY != UNDEF_PIN)
50 pinMode(GPIO_PIN_BUSY, INPUT);
52 if (GPIO_PIN_BUSY_2 != UNDEF_PIN)
54 pinMode(GPIO_PIN_BUSY_2, INPUT);
57 pinMode(GPIO_PIN_DIO1, INPUT);
58 if (GPIO_PIN_DIO1_2 != UNDEF_PIN)
60 pinMode(GPIO_PIN_DIO1_2, INPUT);
63 pinMode(GPIO_PIN_NSS, OUTPUT);
64 digitalWrite(GPIO_PIN_NSS, HIGH);
66 #ifdef PLATFORM_ESP32
67 SPIEx.begin(GPIO_PIN_SCK, GPIO_PIN_MISO, GPIO_PIN_MOSI, GPIO_PIN_NSS); // sck, miso, mosi, ss (ss can be any GPIO)
68 gpio_pullup_en((gpio_num_t)GPIO_PIN_MISO);
69 SPIEx.setFrequency(17500000);
70 SPIEx.setHwCs(true);
71 if (GPIO_PIN_NSS_2 != UNDEF_PIN)
73 pinMode(GPIO_PIN_NSS_2, OUTPUT);
74 digitalWrite(GPIO_PIN_NSS_2, HIGH);
75 spiAttachSS(SPIEx.bus(), 1, GPIO_PIN_NSS_2);
77 spiEnableSSPins(SPIEx.bus(), SX12XX_Radio_All);
78 #elif defined(PLATFORM_ESP8266)
79 DBGLN("PLATFORM_ESP8266");
80 SPIEx.begin();
81 SPIEx.setHwCs(true);
82 SPIEx.setBitOrder(MSBFIRST);
83 SPIEx.setDataMode(SPI_MODE0);
84 SPIEx.setFrequency(17500000);
85 #elif defined(PLATFORM_STM32)
86 DBGLN("Config SPI");
87 SPIEx.setBitOrder(MSBFIRST);
88 SPIEx.setDataMode(SPI_MODE0);
89 SPIEx.setMOSI(GPIO_PIN_MOSI);
90 SPIEx.setMISO(GPIO_PIN_MISO);
91 SPIEx.setSCLK(GPIO_PIN_SCK);
92 SPIEx.begin();
93 SPIEx.setClockDivider(SPI_CLOCK_DIV4); // 72 / 8 = 9 MHz
94 #endif
96 //attachInterrupt(digitalPinToInterrupt(GPIO_PIN_BUSY), this->busyISR, CHANGE); //not used atm
97 attachInterrupt(digitalPinToInterrupt(GPIO_PIN_DIO1), this->dioISR_1, RISING);
98 if (GPIO_PIN_DIO1_2 != UNDEF_PIN)
100 attachInterrupt(digitalPinToInterrupt(GPIO_PIN_DIO1_2), this->dioISR_2, RISING);
104 void SX1280Hal::reset(void)
106 DBGLN("SX1280 Reset");
108 if (GPIO_PIN_RST != UNDEF_PIN)
110 pinMode(GPIO_PIN_RST, OUTPUT);
111 digitalWrite(GPIO_PIN_RST, LOW);
112 if (GPIO_PIN_RST_2 != UNDEF_PIN)
114 pinMode(GPIO_PIN_RST_2, OUTPUT);
115 digitalWrite(GPIO_PIN_RST_2, LOW);
117 delay(50);
118 digitalWrite(GPIO_PIN_RST, HIGH);
119 if (GPIO_PIN_RST_2 != UNDEF_PIN)
121 digitalWrite(GPIO_PIN_RST_2, HIGH);
123 delay(50); // Safety buffer. Busy takes longer to go low than the 1ms timeout in WaitOnBusy().
126 BusyDelay(10000); // 10ms delay if GPIO_PIN_BUSY is undefined
127 WaitOnBusy(SX12XX_Radio_All);
129 //this->BusyState = SX1280_NOT_BUSY;
130 DBGLN("SX1280 Ready!");
133 void ICACHE_RAM_ATTR SX1280Hal::WriteCommand(SX1280_RadioCommands_t command, uint8_t val, SX12XX_Radio_Number_t radioNumber, uint32_t busyDelay)
135 WriteCommand(command, &val, 1, radioNumber, busyDelay);
138 void ICACHE_RAM_ATTR SX1280Hal::WriteCommand(SX1280_RadioCommands_t command, uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber, uint32_t busyDelay)
140 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(size + 1)] = {
141 command,
144 memcpy(OutBuffer + 1, buffer, size);
146 WaitOnBusy(radioNumber);
147 SPIEx.write(radioNumber, OutBuffer, size + 1);
149 BusyDelay(busyDelay);
152 void ICACHE_RAM_ATTR SX1280Hal::ReadCommand(SX1280_RadioCommands_t command, uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber)
154 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(size + 2)] = {
155 (uint8_t)command,
156 0x00,
157 0x00,
160 WaitOnBusy(radioNumber);
162 if (command == SX1280_RADIO_GET_STATUS)
164 const auto RADIO_GET_STATUS_BUF_SIZEOF = 3; // special case for command == SX1280_RADIO_GET_STATUS, fixed 3 bytes packet size
165 SPIEx.read(radioNumber, OutBuffer, RADIO_GET_STATUS_BUF_SIZEOF);
166 buffer[0] = OutBuffer[0];
168 else
170 SPIEx.read(radioNumber, OutBuffer, size + 2); // first 2 bytes returned are status!
171 memcpy(buffer, OutBuffer + 2, size);
175 void ICACHE_RAM_ATTR SX1280Hal::WriteRegister(uint16_t address, uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber)
177 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(size + 3)] = {
178 SX1280_RADIO_WRITE_REGISTER,
179 (uint8_t)((address & 0xFF00) >> 8),
180 (uint8_t)(address & 0x00FF),
183 memcpy(OutBuffer + 3, buffer, size);
185 WaitOnBusy(radioNumber);
186 SPIEx.write(radioNumber, OutBuffer, size + 3);
188 BusyDelay(15);
191 void ICACHE_RAM_ATTR SX1280Hal::WriteRegister(uint16_t address, uint8_t value, SX12XX_Radio_Number_t radioNumber)
193 WriteRegister(address, &value, 1, radioNumber);
196 void ICACHE_RAM_ATTR SX1280Hal::ReadRegister(uint16_t address, uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber)
198 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(size + 4)] = {
199 SX1280_RADIO_READ_REGISTER,
200 (uint8_t)((address & 0xFF00) >> 8),
201 (uint8_t)(address & 0x00FF),
202 0x00,
205 WaitOnBusy(radioNumber);
207 SPIEx.read(radioNumber, OutBuffer, size + 4);
208 memcpy(buffer, OutBuffer + 4, size);
211 uint8_t ICACHE_RAM_ATTR SX1280Hal::ReadRegister(uint16_t address, SX12XX_Radio_Number_t radioNumber)
213 uint8_t data;
214 ReadRegister(address, &data, 1, radioNumber);
215 return data;
218 void ICACHE_RAM_ATTR SX1280Hal::WriteBuffer(uint8_t offset, uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber)
220 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(size + 2)] = {
221 SX1280_RADIO_WRITE_BUFFER,
222 offset
225 memcpy(OutBuffer + 2, buffer, size);
227 WaitOnBusy(radioNumber);
229 SPIEx.write(radioNumber, OutBuffer, size + 2);
231 BusyDelay(15);
234 void ICACHE_RAM_ATTR SX1280Hal::ReadBuffer(uint8_t offset, uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber)
236 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(size + 3)] = {
237 SX1280_RADIO_READ_BUFFER,
238 offset,
239 0x00
242 WaitOnBusy(radioNumber);
244 SPIEx.read(radioNumber, OutBuffer, size + 3);
246 memcpy(buffer, OutBuffer + 3, size);
249 bool ICACHE_RAM_ATTR SX1280Hal::WaitOnBusy(SX12XX_Radio_Number_t radioNumber)
251 if (GPIO_PIN_BUSY != UNDEF_PIN)
253 constexpr uint32_t wtimeoutUS = 1000U;
254 uint32_t startTime = 0;
256 while (true)
258 if (radioNumber == SX12XX_Radio_1)
260 if (digitalRead(GPIO_PIN_BUSY) == LOW) return true;
262 else if (radioNumber == SX12XX_Radio_2)
264 if (GPIO_PIN_BUSY_2 == UNDEF_PIN || digitalRead(GPIO_PIN_BUSY_2) == LOW) return true;
266 else if (radioNumber == SX12XX_Radio_All)
268 if (GPIO_PIN_BUSY_2 != UNDEF_PIN)
270 if (digitalRead(GPIO_PIN_BUSY) == LOW && digitalRead(GPIO_PIN_BUSY_2) == LOW) return true;
272 else
274 if (digitalRead(GPIO_PIN_BUSY) == LOW) return true;
277 // Use this time to call micros().
278 uint32_t now = micros();
279 if (startTime == 0) startTime = now;
280 if ((now - startTime) > wtimeoutUS) return false;
283 else
285 uint32_t now = micros();
286 while ((now - BusyDelayStart) < BusyDelayDuration)
287 now = micros();
288 BusyDelayDuration = 0;
290 return true;
293 void ICACHE_RAM_ATTR SX1280Hal::dioISR_1()
295 if (instance->IsrCallback_1)
296 instance->IsrCallback_1();
299 void ICACHE_RAM_ATTR SX1280Hal::dioISR_2()
301 if (instance->IsrCallback_2)
302 instance->IsrCallback_2();
305 #endif // UNIT_TEST