3 #include "LR1121_hal.h"
4 #include "LR1121_Regs.h"
8 LR1121Hal
*LR1121Hal::instance
= NULL
;
10 LR1121Hal::LR1121Hal()
17 detachInterrupt(GPIO_PIN_DIO1
);
18 if (GPIO_PIN_DIO1_2
!= UNDEF_PIN
)
20 detachInterrupt(GPIO_PIN_DIO1_2
);
23 IsrCallback_1
= nullptr;
24 IsrCallback_2
= nullptr;
27 void LR1121Hal::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
);
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);
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");
67 SPIEx
.setBitOrder(MSBFIRST
);
68 SPIEx
.setDataMode(SPI_MODE0
);
69 SPIEx
.setFrequency(17500000);
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
)
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
)
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
);
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.
111 pinMode(GPIO_PIN_BUSY
, INPUT
);
112 if (GPIO_PIN_RST_2
!= UNDEF_PIN
)
114 pinMode(GPIO_PIN_BUSY_2
, INPUT
);
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;
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;
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();