Tactiliest/Drivers/RadioLibCompat/Source/RadiolibTactilityHal.cpp

168 lines
4.7 KiB
C++

#include "RadiolibTactilityHal.h"
#include "hal/gpio_hal.h"
#include "esp_timer.h"
constexpr const char* TAG = "RadiolibTactilityHal";
void RadiolibTactilityHal::init() {
// we only need to init the SPI here
spiBegin();
}
void RadiolibTactilityHal::term() {
// we only need to stop the SPI here
spiEnd();
}
void RadiolibTactilityHal::pinMode(uint32_t pin, uint32_t mode) {
if(pin == RADIOLIB_NC) {
return;
}
gpio_hal_context_t gpiohal;
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
gpio_config_t conf = {
.pin_bit_mask = (1ULL<<pin),
.mode = (gpio_mode_t)mode,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = (gpio_int_type_t)gpiohal.dev->pin[pin].int_type,
};
gpio_config(&conf);
}
void RadiolibTactilityHal::digitalWrite(uint32_t pin, uint32_t value) {
if(pin == RADIOLIB_NC) {
return;
}
gpio_set_level((gpio_num_t)pin, value);
}
uint32_t RadiolibTactilityHal::digitalRead(uint32_t pin) {
if(pin == RADIOLIB_NC) {
return(0);
}
return(gpio_get_level((gpio_num_t)pin));
}
void RadiolibTactilityHal::attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) {
if(interruptNum == RADIOLIB_NC) {
return;
}
if (!isrServiceInitialized) {
gpio_install_isr_service((int)ESP_INTR_FLAG_IRAM);
isrServiceInitialized = true;
}
gpio_set_intr_type((gpio_num_t)interruptNum, (gpio_int_type_t)(mode & 0x7));
// this uses function typecasting, which is not defined when the functions have different signatures
// untested and might not work
// TODO: I think the wisest course of action is forbidding registration via RadioLib entirely,
// as it doesn't suit Tactility with its lack of context passing
gpio_isr_handler_add((gpio_num_t)interruptNum, (void (*)(void*))interruptCb, NULL);
}
void RadiolibTactilityHal::detachInterrupt(uint32_t interruptNum) {
if(interruptNum == RADIOLIB_NC) {
return;
}
gpio_isr_handler_remove((gpio_num_t)interruptNum);
gpio_wakeup_disable((gpio_num_t)interruptNum);
gpio_set_intr_type((gpio_num_t)interruptNum, GPIO_INTR_DISABLE);
}
void RadiolibTactilityHal::delay(unsigned long ms) {
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void RadiolibTactilityHal::delayMicroseconds(unsigned long us) {
uint64_t m = (uint64_t)esp_timer_get_time();
if(us) {
uint64_t e = (m + us);
if(m > e) { // overflow
while((uint64_t)esp_timer_get_time() > e);
}
while((uint64_t)esp_timer_get_time() < e);
}
}
unsigned long RadiolibTactilityHal::millis() {
return((unsigned long)(esp_timer_get_time() / 1000ULL));
}
unsigned long RadiolibTactilityHal::micros() {
return((unsigned long)(esp_timer_get_time()));
}
long RadiolibTactilityHal::pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) {
if(pin == RADIOLIB_NC) {
return(0);
}
this->pinMode(pin, GPIO_MODE_INPUT);
uint32_t start = this->micros();
uint32_t curtick = this->micros();
while(this->digitalRead(pin) == state) {
if((this->micros() - curtick) > timeout) {
return(0);
}
}
return(this->micros() - start);
}
void RadiolibTactilityHal::spiBegin() {
if (!spiInitialized) {
TT_LOG_I(TAG, "SPI Begin!");
spi_device_interface_config_t devcfg = {};
devcfg.clock_speed_hz = spiFrequency;
devcfg.mode = 0;
devcfg.spics_io_num = csPin;
devcfg.queue_size = 1;
esp_err_t ret = spi_bus_add_device(spiHostDevice, &devcfg, &spiDeviceHandle);
if (ret != ESP_OK) {
TT_LOG_E(TAG, "Failed to add SPI device: %s", esp_err_to_name(ret));
}
spiInitialized = true;
}
}
void RadiolibTactilityHal::spiBeginTransaction() {
// This function is used to set up the transaction (speed, bit order, mode, ...).
// With the ESP-IDF HAL this is automatically done, so no code needed.
}
void RadiolibTactilityHal::spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
spi_transaction_t t;
auto lock = getLock()->asScopedLock();
bool locked = lock.lock(portMAX_DELAY);
if (!locked) {
TT_LOG_E(TAG, "Failed to aquire SPI lock");
}
memset(&t, 0, sizeof(t)); // Zero out the transaction
t.length = len * 8; // Length is in bits
t.tx_buffer = out; // The data to send
t.rx_buffer = in; // The data to receive
spi_device_polling_transmit(spiDeviceHandle, &t);
}
void RadiolibTactilityHal::spiEndTransaction() {
// nothing needs to be done here
}
void RadiolibTactilityHal::spiEnd() {
if (spiInitialized) {
spi_bus_remove_device(spiDeviceHandle);
spiInitialized = false;
}
}