Communicate Rx available antenna mode to the Tx (#3039)
[ExpressLRS.git] / src / lib / LR1121Driver / LR1121_hal.cpp
blobab03999055dcbdec60ca1f28cc17928c92fdd813
1 #ifndef UNIT_TEST
3 #include "LR1121_hal.h"
4 #include "LR1121_Regs.h"
5 #include "logging.h"
6 #include <SPIEx.h>
8 LR1121Hal *LR1121Hal::instance = NULL;
10 LR1121Hal::LR1121Hal()
12 instance = this;
15 void LR1121Hal::end()
17 detachInterrupt(GPIO_PIN_DIO1);
18 if (GPIO_PIN_DIO1_2 != UNDEF_PIN)
20 detachInterrupt(GPIO_PIN_DIO1_2);
22 SPIEx.end();
23 IsrCallback_1 = nullptr;
24 IsrCallback_2 = nullptr;
27 void LR1121Hal::init()
29 DBGLN("Hal Init");
31 pinMode(GPIO_PIN_BUSY, INPUT);
32 if (GPIO_PIN_BUSY_2 != UNDEF_PIN)
34 pinMode(GPIO_PIN_BUSY_2, INPUT);
37 pinMode(GPIO_PIN_DIO1, INPUT);
38 if (GPIO_PIN_DIO1_2 != UNDEF_PIN)
40 pinMode(GPIO_PIN_DIO1_2, INPUT);
43 pinMode(GPIO_PIN_NSS, OUTPUT);
44 digitalWrite(GPIO_PIN_NSS, HIGH);
45 if (GPIO_PIN_NSS_2 != UNDEF_PIN)
47 pinMode(GPIO_PIN_NSS_2, OUTPUT);
48 digitalWrite(GPIO_PIN_NSS_2, HIGH);
51 #ifdef PLATFORM_ESP32
52 SPIEx.begin(GPIO_PIN_SCK, GPIO_PIN_MISO, GPIO_PIN_MOSI, GPIO_PIN_NSS); // sck, miso, mosi, ss (ss can be any GPIO)
53 gpio_pullup_en((gpio_num_t)GPIO_PIN_MISO);
54 SPIEx.setFrequency(17500000);
55 SPIEx.setHwCs(true);
56 if (GPIO_PIN_NSS_2 != UNDEF_PIN)
58 pinMode(GPIO_PIN_NSS_2, OUTPUT);
59 digitalWrite(GPIO_PIN_NSS_2, HIGH);
60 spiAttachSS(SPIEx.bus(), 1, GPIO_PIN_NSS_2);
62 spiEnableSSPins(SPIEx.bus(), SX12XX_Radio_All);
63 #elif defined(PLATFORM_ESP8266)
64 DBGLN("PLATFORM_ESP8266");
65 SPIEx.begin();
66 SPIEx.setHwCs(true);
67 SPIEx.setBitOrder(MSBFIRST);
68 SPIEx.setDataMode(SPI_MODE0);
69 SPIEx.setFrequency(17500000);
70 #endif
72 attachInterrupt(digitalPinToInterrupt(GPIO_PIN_DIO1), this->dioISR_1, RISING);
73 if (GPIO_PIN_DIO1_2 != UNDEF_PIN)
75 attachInterrupt(digitalPinToInterrupt(GPIO_PIN_DIO1_2), this->dioISR_2, RISING);
79 void LR1121Hal::reset(bool bootloader)
81 DBGLN("LR1121 Reset");
83 if (GPIO_PIN_RST != UNDEF_PIN)
85 if (bootloader)
87 pinMode(GPIO_PIN_BUSY, OUTPUT);
88 digitalWrite(GPIO_PIN_BUSY, LOW);
90 pinMode(GPIO_PIN_RST, OUTPUT);
91 digitalWrite(GPIO_PIN_RST, LOW);
92 if (GPIO_PIN_RST_2 != UNDEF_PIN)
94 if (bootloader)
96 pinMode(GPIO_PIN_BUSY_2, OUTPUT);
97 digitalWrite(GPIO_PIN_BUSY_2, LOW);
99 pinMode(GPIO_PIN_RST_2, OUTPUT);
100 digitalWrite(GPIO_PIN_RST_2, LOW);
102 delay(1);
103 digitalWrite(GPIO_PIN_RST, HIGH);
104 if (GPIO_PIN_RST_2 != UNDEF_PIN)
106 digitalWrite(GPIO_PIN_RST_2, HIGH);
108 delay(300); // LR1121 busy is high for 230ms after reset. The WaitOnBusy timeout is only 1ms. So this long delay is required.
109 if (bootloader)
111 pinMode(GPIO_PIN_BUSY, INPUT);
112 if (GPIO_PIN_RST_2 != UNDEF_PIN)
114 pinMode(GPIO_PIN_BUSY_2, INPUT);
116 delay(100);
120 WaitOnBusy(SX12XX_Radio_All);
123 void ICACHE_RAM_ATTR LR1121Hal::WriteCommand(uint16_t command, uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber)
125 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(size + 2)] = {
126 (uint8_t)((command & 0xFF00) >> 8),
127 (uint8_t)(command & 0x00FF),
130 memcpy(OutBuffer + 2, buffer, size);
132 WaitOnBusy(radioNumber);
133 SPIEx.write(radioNumber, OutBuffer, size + 2);
136 void ICACHE_RAM_ATTR LR1121Hal::WriteCommand(uint16_t command, SX12XX_Radio_Number_t radioNumber)
138 WORD_ALIGNED_ATTR uint8_t OutBuffer[WORD_PADDED(2)] = {
139 (uint8_t)((command & 0xFF00) >> 8),
140 (uint8_t)(command & 0x00FF)
143 WaitOnBusy(radioNumber);
144 SPIEx.write(radioNumber, OutBuffer, 2);
147 void ICACHE_RAM_ATTR LR1121Hal::ReadCommand(uint8_t *buffer, uint8_t size, SX12XX_Radio_Number_t radioNumber)
149 WORD_ALIGNED_ATTR uint8_t InBuffer[WORD_PADDED(size)] = {0};
151 memcpy(InBuffer, buffer, size);
153 WaitOnBusy(radioNumber);
154 SPIEx.read(radioNumber, InBuffer, size);
156 memcpy(buffer, InBuffer, size);
159 bool ICACHE_RAM_ATTR LR1121Hal::WaitOnBusy(SX12XX_Radio_Number_t radioNumber)
161 constexpr uint32_t wtimeoutUS = 1000U;
162 uint32_t startTime = 0;
164 while (true)
166 if (radioNumber == SX12XX_Radio_1)
168 if (digitalRead(GPIO_PIN_BUSY) == LOW) return true;
170 else if (radioNumber == SX12XX_Radio_2)
172 if (GPIO_PIN_BUSY_2 == UNDEF_PIN || digitalRead(GPIO_PIN_BUSY_2) == LOW) return true;
174 else if (radioNumber == SX12XX_Radio_All)
176 if (GPIO_PIN_BUSY_2 != UNDEF_PIN)
178 if (digitalRead(GPIO_PIN_BUSY) == LOW && digitalRead(GPIO_PIN_BUSY_2) == LOW) return true;
180 else
182 if (digitalRead(GPIO_PIN_BUSY) == LOW) return true;
185 // Use this time to call micros().
186 uint32_t now = micros();
187 if (startTime == 0) startTime = now;
188 if ((now - startTime) > wtimeoutUS) return false;
192 void ICACHE_RAM_ATTR LR1121Hal::dioISR_1()
194 if (instance->IsrCallback_1)
195 instance->IsrCallback_1();
198 void ICACHE_RAM_ATTR LR1121Hal::dioISR_2()
200 if (instance->IsrCallback_2)
201 instance->IsrCallback_2();
204 #endif // UNIT_TEST