4 ( (____ _____ ____ _| |_ _____ ____| |__
5 \____ \| ___ | (_ _) ___ |/ ___) _ \
6 _____) ) ____| | | || |_| ____( (___| | | |
7 (______/|_____)_|_|_| \__)_____)\____)_| |_|
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
20 #include "SX1280_Regs.h"
21 #include "SX1280_hal.h"
25 SX1280Hal
*SX1280Hal::instance
= NULL
;
27 SX1280Hal::SX1280Hal()
34 RXenable(); // make sure the TX amp pin is disabled
35 detachInterrupt(GPIO_PIN_DIO1
);
37 IsrCallback
= nullptr; // remove callbacks
40 void SX1280Hal::init()
43 #if defined(GPIO_PIN_BUSY) && (GPIO_PIN_BUSY != UNDEF_PIN)
44 pinMode(GPIO_PIN_BUSY
, INPUT
);
46 pinMode(GPIO_PIN_DIO1
, INPUT
);
47 pinMode(GPIO_PIN_NSS
, OUTPUT
);
48 digitalWrite(GPIO_PIN_NSS
, HIGH
);
50 #if defined(GPIO_PIN_PA_ENABLE) && (GPIO_PIN_PA_ENABLE != UNDEF_PIN)
51 DBGLN("Use PA ctrl pin: %d", GPIO_PIN_PA_ENABLE
);
52 pinMode(GPIO_PIN_PA_ENABLE
, OUTPUT
);
53 digitalWrite(GPIO_PIN_PA_ENABLE
, LOW
);
56 #if defined(GPIO_PIN_PA_SE2622L_ENABLE) && (GPIO_PIN_PA_SE2622L_ENABLE != UNDEF_PIN)
57 DBGLN("Use PA ctrl pin: %d", GPIO_PIN_PA_SE2622L_ENABLE
);
58 pinMode(GPIO_PIN_PA_SE2622L_ENABLE
, OUTPUT
);
59 digitalWrite(GPIO_PIN_PA_SE2622L_ENABLE
, LOW
);
62 #if defined(GPIO_PIN_TX_ENABLE) && (GPIO_PIN_TX_ENABLE != UNDEF_PIN)
63 DBGLN("Use TX pin: %d", GPIO_PIN_TX_ENABLE
);
64 pinMode(GPIO_PIN_TX_ENABLE
, OUTPUT
);
65 digitalWrite(GPIO_PIN_TX_ENABLE
, LOW
);
68 #if defined(GPIO_PIN_RX_ENABLE) && (GPIO_PIN_RX_ENABLE != UNDEF_PIN)
69 DBGLN("Use RX pin: %d", GPIO_PIN_RX_ENABLE
);
70 pinMode(GPIO_PIN_RX_ENABLE
, OUTPUT
);
71 digitalWrite(GPIO_PIN_RX_ENABLE
, LOW
);
74 #if defined(GPIO_PIN_ANT_CTRL_1) && (GPIO_PIN_ANT_CTRL_1 != UNDEF_PIN)
75 pinMode(GPIO_PIN_ANT_CTRL_1
, OUTPUT
);
76 digitalWrite(GPIO_PIN_ANT_CTRL_1
, HIGH
);
79 #if defined(GPIO_PIN_ANT_CTRL_2) && (GPIO_PIN_ANT_CTRL_2 != UNDEF_PIN)
80 pinMode(GPIO_PIN_ANT_CTRL_2
, OUTPUT
);
81 digitalWrite(GPIO_PIN_ANT_CTRL_2
, LOW
);
85 SPI
.begin(GPIO_PIN_SCK
, GPIO_PIN_MISO
, GPIO_PIN_MOSI
, -1); // sck, miso, mosi, ss (ss can be any GPIO)
86 gpio_pullup_en((gpio_num_t
)GPIO_PIN_MISO
);
87 SPI
.setFrequency(10000000);
90 #ifdef PLATFORM_ESP8266
91 DBGLN("PLATFORM_ESP8266");
93 SPI
.setBitOrder(MSBFIRST
);
94 SPI
.setDataMode(SPI_MODE0
);
95 SPI
.setFrequency(10000000);
100 SPI
.setMOSI(GPIO_PIN_MOSI
);
101 SPI
.setMISO(GPIO_PIN_MISO
);
102 SPI
.setSCLK(GPIO_PIN_SCK
);
103 SPI
.setBitOrder(MSBFIRST
);
104 SPI
.setDataMode(SPI_MODE0
);
106 SPI
.setClockDivider(SPI_CLOCK_DIV4
); // 72 / 8 = 9 MHz
109 //attachInterrupt(digitalPinToInterrupt(GPIO_PIN_BUSY), this->busyISR, CHANGE); //not used atm
110 attachInterrupt(digitalPinToInterrupt(GPIO_PIN_DIO1
), this->dioISR
, RISING
);
113 void SX1280Hal::reset(void)
115 DBGLN("SX1280 Reset");
117 #if defined(GPIO_PIN_RST)
118 pinMode(GPIO_PIN_RST
, OUTPUT
);
121 digitalWrite(GPIO_PIN_RST
, LOW
);
123 digitalWrite(GPIO_PIN_RST
, HIGH
);
126 #if defined(GPIO_PIN_BUSY) && (GPIO_PIN_BUSY != UNDEF_PIN)
127 while (digitalRead(GPIO_PIN_BUSY
) == HIGH
) // wait for busy
129 #ifdef PLATFORM_STM32
133 #elif PLATFORM_ESP8266
138 delay(10); // typically 2ms observed
141 //this->BusyState = SX1280_NOT_BUSY;
142 DBGLN("SX1280 Ready!");
145 void ICACHE_RAM_ATTR
SX1280Hal::WriteCommand(SX1280_RadioCommands_t command
, uint8_t val
)
148 digitalWrite(GPIO_PIN_NSS
, LOW
);
150 SPI
.transfer((uint8_t)command
);
153 digitalWrite(GPIO_PIN_NSS
, HIGH
);
158 void ICACHE_RAM_ATTR
SX1280Hal::WriteCommand(SX1280_RadioCommands_t command
, uint8_t *buffer
, uint8_t size
)
160 WORD_ALIGNED_ATTR
uint8_t OutBuffer
[size
+ 1];
162 OutBuffer
[0] = (uint8_t)command
;
163 memcpy(OutBuffer
+ 1, buffer
, size
);
166 digitalWrite(GPIO_PIN_NSS
, LOW
);
167 SPI
.transfer(OutBuffer
, (uint8_t)sizeof(OutBuffer
));
168 digitalWrite(GPIO_PIN_NSS
, HIGH
);
173 void ICACHE_RAM_ATTR
SX1280Hal::ReadCommand(SX1280_RadioCommands_t command
, uint8_t *buffer
, uint8_t size
)
175 WORD_ALIGNED_ATTR
uint8_t OutBuffer
[size
+ 2];
176 #define RADIO_GET_STATUS_BUF_SIZEOF 3 // special case for command == SX1280_RADIO_GET_STATUS, fixed 3 bytes packet size
179 digitalWrite(GPIO_PIN_NSS
, LOW
);
181 if (command
== SX1280_RADIO_GET_STATUS
)
183 OutBuffer
[0] = (uint8_t)command
;
186 SPI
.transfer(OutBuffer
, RADIO_GET_STATUS_BUF_SIZEOF
);
187 buffer
[0] = OutBuffer
[0];
191 OutBuffer
[0] = (uint8_t)command
;
193 memcpy(OutBuffer
+ 2, buffer
, size
);
194 SPI
.transfer(OutBuffer
, sizeof(OutBuffer
));
195 memcpy(buffer
, OutBuffer
+ 2, size
);
197 digitalWrite(GPIO_PIN_NSS
, HIGH
);
200 void ICACHE_RAM_ATTR
SX1280Hal::WriteRegister(uint16_t address
, uint8_t *buffer
, uint8_t size
)
202 WORD_ALIGNED_ATTR
uint8_t OutBuffer
[size
+ 3];
204 OutBuffer
[0] = (SX1280_RADIO_WRITE_REGISTER
);
205 OutBuffer
[1] = ((address
& 0xFF00) >> 8);
206 OutBuffer
[2] = (address
& 0x00FF);
208 memcpy(OutBuffer
+ 3, buffer
, size
);
211 digitalWrite(GPIO_PIN_NSS
, LOW
);
212 SPI
.transfer(OutBuffer
, (uint8_t)sizeof(OutBuffer
));
213 digitalWrite(GPIO_PIN_NSS
, HIGH
);
218 void ICACHE_RAM_ATTR
SX1280Hal::WriteRegister(uint16_t address
, uint8_t value
)
220 WriteRegister(address
, &value
, 1);
223 void ICACHE_RAM_ATTR
SX1280Hal::ReadRegister(uint16_t address
, uint8_t *buffer
, uint8_t size
)
225 WORD_ALIGNED_ATTR
uint8_t OutBuffer
[size
+ 4];
227 OutBuffer
[0] = (SX1280_RADIO_READ_REGISTER
);
228 OutBuffer
[1] = ((address
& 0xFF00) >> 8);
229 OutBuffer
[2] = (address
& 0x00FF);
233 digitalWrite(GPIO_PIN_NSS
, LOW
);
235 SPI
.transfer(OutBuffer
, uint8_t(sizeof(OutBuffer
)));
236 memcpy(buffer
, OutBuffer
+ 4, size
);
238 digitalWrite(GPIO_PIN_NSS
, HIGH
);
241 uint8_t ICACHE_RAM_ATTR
SX1280Hal::ReadRegister(uint16_t address
)
244 ReadRegister(address
, &data
, 1);
248 void ICACHE_RAM_ATTR
SX1280Hal::WriteBuffer(uint8_t offset
, volatile uint8_t *buffer
, uint8_t size
)
250 uint8_t localbuf
[size
];
252 for (int i
= 0; i
< size
; i
++) // todo check if this is the right want to handle volatiles
254 localbuf
[i
] = buffer
[i
];
257 WORD_ALIGNED_ATTR
uint8_t OutBuffer
[size
+ 2];
259 OutBuffer
[0] = SX1280_RADIO_WRITE_BUFFER
;
260 OutBuffer
[1] = offset
;
262 memcpy(OutBuffer
+ 2, localbuf
, size
);
266 digitalWrite(GPIO_PIN_NSS
, LOW
);
267 SPI
.transfer(OutBuffer
, (uint8_t)sizeof(OutBuffer
));
268 digitalWrite(GPIO_PIN_NSS
, HIGH
);
273 void ICACHE_RAM_ATTR
SX1280Hal::ReadBuffer(uint8_t offset
, volatile uint8_t *buffer
, uint8_t size
)
275 WORD_ALIGNED_ATTR
uint8_t OutBuffer
[size
+ 3];
276 uint8_t localbuf
[size
];
278 OutBuffer
[0] = SX1280_RADIO_READ_BUFFER
;
279 OutBuffer
[1] = offset
;
283 digitalWrite(GPIO_PIN_NSS
, LOW
);
285 SPI
.transfer(OutBuffer
, uint8_t(sizeof(OutBuffer
)));
286 digitalWrite(GPIO_PIN_NSS
, HIGH
);
288 memcpy(localbuf
, OutBuffer
+ 3, size
);
290 for (int i
= 0; i
< size
; i
++) // todo check if this is the right wany to handle volatiles
292 buffer
[i
] = localbuf
[i
];
296 bool ICACHE_RAM_ATTR
SX1280Hal::WaitOnBusy()
298 #if defined(GPIO_PIN_BUSY) && (GPIO_PIN_BUSY != UNDEF_PIN)
299 #define wtimeoutUS 1000
300 uint32_t startTime
= micros();
302 while (digitalRead(GPIO_PIN_BUSY
) == HIGH
) // wait untill not busy or until wtimeoutUS
304 if ((micros() - startTime
) > wtimeoutUS
)
311 #ifdef PLATFORM_STM32
315 #elif PLATFORM_ESP8266
321 // observed BUSY time for Write* calls are 12-20uS after NSS de-assert
322 // and state transitions require extra time depending on prior state
323 if (BusyDelayDuration
)
325 while ((micros() - BusyDelayStart
) < BusyDelayDuration
)
326 #ifdef PLATFORM_STM32
330 #elif PLATFORM_ESP8266
333 BusyDelayDuration
= 0;
335 // delayMicroseconds(80);
340 void ICACHE_RAM_ATTR
SX1280Hal::dioISR()
342 if (instance
->IsrCallback
)
343 instance
->IsrCallback();
346 void ICACHE_RAM_ATTR
SX1280Hal::TXenable()
348 #if defined(GPIO_PIN_PA_ENABLE) && (GPIO_PIN_PA_ENABLE != UNDEF_PIN)
349 digitalWrite(GPIO_PIN_PA_ENABLE
, HIGH
);
351 #if defined(GPIO_PIN_RX_ENABLE) && (GPIO_PIN_RX_ENABLE != UNDEF_PIN)
352 digitalWrite(GPIO_PIN_RX_ENABLE
, LOW
);
354 #if defined(GPIO_PIN_TX_ENABLE) && (GPIO_PIN_TX_ENABLE != UNDEF_PIN)
355 digitalWrite(GPIO_PIN_TX_ENABLE
, HIGH
);
357 #if defined(GPIO_PIN_ANT_CTRL_1) && (GPIO_PIN_ANT_CTRL_1 != UNDEF_PIN)
358 digitalWrite(GPIO_PIN_ANT_CTRL_1
, HIGH
);
360 #if defined(GPIO_PIN_ANT_CTRL_2) && (GPIO_PIN_ANT_CTRL_2 != UNDEF_PIN)
361 digitalWrite(GPIO_PIN_ANT_CTRL_2
, LOW
);
365 void ICACHE_RAM_ATTR
SX1280Hal::RXenable()
367 #if defined(GPIO_PIN_PA_ENABLE) && (GPIO_PIN_PA_ENABLE != UNDEF_PIN)
368 digitalWrite(GPIO_PIN_PA_ENABLE
, HIGH
);
370 #if defined(GPIO_PIN_RX_ENABLE) && (GPIO_PIN_RX_ENABLE != UNDEF_PIN)
371 digitalWrite(GPIO_PIN_RX_ENABLE
, HIGH
);
373 #if defined(GPIO_PIN_TX_ENABLE) && (GPIO_PIN_TX_ENABLE != UNDEF_PIN)
374 digitalWrite(GPIO_PIN_TX_ENABLE
, LOW
);
376 #if defined(GPIO_PIN_ANT_CTRL_1) && (GPIO_PIN_ANT_CTRL_1 != UNDEF_PIN)
377 digitalWrite(GPIO_PIN_ANT_CTRL_1
, LOW
);
379 #if defined(GPIO_PIN_ANT_CTRL_2) && (GPIO_PIN_ANT_CTRL_2 != UNDEF_PIN)
380 digitalWrite(GPIO_PIN_ANT_CTRL_2
, HIGH
);
384 void ICACHE_RAM_ATTR
SX1280Hal::TXRXdisable()
386 #if defined(GPIO_PIN_RX_ENABLE) && (GPIO_PIN_RX_ENABLE != UNDEF_PIN)
387 digitalWrite(GPIO_PIN_RX_ENABLE
, LOW
);
389 #if defined(GPIO_PIN_TX_ENABLE) && (GPIO_PIN_TX_ENABLE != UNDEF_PIN)
390 digitalWrite(GPIO_PIN_TX_ENABLE
, LOW
);
392 #if defined(GPIO_PIN_PA_ENABLE) && (GPIO_PIN_PA_ENABLE != UNDEF_PIN)
393 digitalWrite(GPIO_PIN_PA_ENABLE
, LOW
);