More transformation to C++

This commit is contained in:
Manuel Bleichenbacher 2018-10-27 23:55:36 +02:00
parent f03b5c51fd
commit 58116219bb
4 changed files with 233 additions and 173 deletions

View File

@ -283,9 +283,9 @@ void TTNProvisioning::processLine()
if (reset_needed) if (reset_needed)
{ {
hal_enterCriticalSection(); ttn_hal.enterCriticalSection();
LMIC_reset(); LMIC_reset();
hal_leaveCriticalSection(); ttn_hal.leaveCriticalSection();
onEvent(EV_RESET); onEvent(EV_RESET);
} }

View File

@ -45,7 +45,7 @@ TheThingsNetwork::TheThingsNetwork()
ASSERT(ttnInstance == nullptr); ASSERT(ttnInstance == nullptr);
ttnInstance = this; ttnInstance = this;
hal_initCriticalSection(); ttn_hal.initCriticalSection();
} }
TheThingsNetwork::~TheThingsNetwork() TheThingsNetwork::~TheThingsNetwork()
@ -67,14 +67,14 @@ void TheThingsNetwork::configurePins(spi_host_device_t spi_host, uint8_t nss, ui
resultQueue = xQueueCreate(12, sizeof(int)); resultQueue = xQueueCreate(12, sizeof(int));
ASSERT(resultQueue != nullptr); ASSERT(resultQueue != nullptr);
hal_startBgTask(); ttn_hal.startBackgroundTask();
} }
void TheThingsNetwork::reset() void TheThingsNetwork::reset()
{ {
hal_enterCriticalSection(); ttn_hal.enterCriticalSection();
LMIC_reset(); LMIC_reset();
hal_leaveCriticalSection(); ttn_hal.leaveCriticalSection();
} }
bool TheThingsNetwork::provision(const char *devEui, const char *appEui, const char *appKey) bool TheThingsNetwork::provision(const char *devEui, const char *appEui, const char *appKey)
@ -152,11 +152,11 @@ bool TheThingsNetwork::joinCore()
return false; return false;
} }
hal_enterCriticalSection(); ttn_hal.enterCriticalSection();
clientAction = eActionJoining; clientAction = eActionJoining;
LMIC_startJoining(); LMIC_startJoining();
hal_wakeUp(); ttn_hal.wakeUp();
hal_leaveCriticalSection(); ttn_hal.leaveCriticalSection();
int result = 0; int result = 0;
xQueueReceive(resultQueue, &result, portMAX_DELAY); xQueueReceive(resultQueue, &result, portMAX_DELAY);
@ -165,17 +165,17 @@ bool TheThingsNetwork::joinCore()
TTNResponseCode TheThingsNetwork::transmitMessage(const uint8_t *payload, size_t length, port_t port, bool confirm) TTNResponseCode TheThingsNetwork::transmitMessage(const uint8_t *payload, size_t length, port_t port, bool confirm)
{ {
hal_enterCriticalSection(); ttn_hal.enterCriticalSection();
if (LMIC.opmode & OP_TXRXPEND) if (LMIC.opmode & OP_TXRXPEND)
{ {
hal_leaveCriticalSection(); ttn_hal.leaveCriticalSection();
return kTTNErrorTransmissionFailed; return kTTNErrorTransmissionFailed;
} }
clientAction = eActionSending; clientAction = eActionSending;
LMIC_setTxData2(port, (xref2u1_t)payload, length, confirm); LMIC_setTxData2(port, (xref2u1_t)payload, length, confirm);
hal_wakeUp(); ttn_hal.wakeUp();
hal_leaveCriticalSection(); ttn_hal.leaveCriticalSection();
int result = 0; int result = 0;
xQueueReceive(resultQueue, &result, portMAX_DELAY); xQueueReceive(resultQueue, &result, portMAX_DELAY);

View File

@ -22,44 +22,44 @@
#define LMIC_UNUSED_PIN 0xff #define LMIC_UNUSED_PIN 0xff
static const char *TAG = "ttn_hal"; static const char * const TAG = "ttn_hal";
lmic_pinmap lmic_pins; lmic_pinmap lmic_pins;
HAL_ESP32 ttn_hal;
typedef enum {
DIO0 = 0,
DIO1,
DIO2,
TIMER,
WAKEUP
} event_t;
typedef struct { struct HALQueueItem {
ostime_t time; ostime_t time;
event_t ev; HAL_Event ev;
} queue_item_t;
HALQueueItem() : time(0), ev(DIO0) { }
HALQueueItem(HAL_Event e, ostime_t t = 0)
: time(t), ev(e) { }
};
// -----------------------------------------------------------------------------
// Constructor
HAL_ESP32::HAL_ESP32()
: nextTimerEvent(0x200000000)
{
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// I/O // I/O
static QueueHandle_t dio_queue; void IRAM_ATTR HAL_ESP32::dioIrqHandler(void *arg)
void IRAM_ATTR dio_irq_handler(void *arg)
{ {
uint64_t now; uint64_t now;
timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now); timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now);
event_t ev = (long)arg; BaseType_t higherPrioTaskWoken = pdFALSE;
BaseType_t higher_prio_task_woken = pdFALSE; HALQueueItem item { (HAL_Event)(long)arg, (ostime_t)now };
queue_item_t item = { xQueueSendFromISR(ttn_hal.dioQueue, &item, &higherPrioTaskWoken);
.time = (ostime_t)now, if (higherPrioTaskWoken)
.ev = ev
};
xQueueSendFromISR(dio_queue, &item, &higher_prio_task_woken);
if (higher_prio_task_woken)
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }
static void hal_io_init() void HAL_ESP32::ioInit()
{ {
// NSS and DIO0 and DIO1 are required // NSS and DIO0 and DIO1 are required
ASSERT(lmic_pins.nss != LMIC_UNUSED_PIN); ASSERT(lmic_pins.nss != LMIC_UNUSED_PIN);
@ -67,35 +67,35 @@ static void hal_io_init()
ASSERT(lmic_pins.dio1 != LMIC_UNUSED_PIN); ASSERT(lmic_pins.dio1 != LMIC_UNUSED_PIN);
gpio_pad_select_gpio(lmic_pins.nss); gpio_pad_select_gpio(lmic_pins.nss);
gpio_set_level(lmic_pins.nss, 0); gpio_set_level((gpio_num_t)lmic_pins.nss, 0);
gpio_set_direction(lmic_pins.nss, GPIO_MODE_OUTPUT); gpio_set_direction((gpio_num_t)lmic_pins.nss, GPIO_MODE_OUTPUT);
if (lmic_pins.rxtx != LMIC_UNUSED_PIN) if (lmic_pins.rxtx != LMIC_UNUSED_PIN)
{ {
gpio_pad_select_gpio(lmic_pins.rxtx); gpio_pad_select_gpio(lmic_pins.rxtx);
gpio_set_level(lmic_pins.rxtx, 0); gpio_set_level((gpio_num_t)lmic_pins.rxtx, 0);
gpio_set_direction(lmic_pins.rxtx, GPIO_MODE_OUTPUT); gpio_set_direction((gpio_num_t)lmic_pins.rxtx, GPIO_MODE_OUTPUT);
} }
if (lmic_pins.rst != LMIC_UNUSED_PIN) if (lmic_pins.rst != LMIC_UNUSED_PIN)
{ {
gpio_pad_select_gpio(lmic_pins.rst); gpio_pad_select_gpio((gpio_num_t)lmic_pins.rst);
gpio_set_level(lmic_pins.rst, 0); gpio_set_level((gpio_num_t)lmic_pins.rst, 0);
gpio_set_direction(lmic_pins.rst, GPIO_MODE_OUTPUT); gpio_set_direction((gpio_num_t)lmic_pins.rst, GPIO_MODE_OUTPUT);
} }
dio_queue = xQueueCreate(12, sizeof(queue_item_t)); dioQueue = xQueueCreate(12, sizeof(HALQueueItem));
ASSERT(dio_queue != NULL); ASSERT(dioQueue != NULL);
gpio_pad_select_gpio(lmic_pins.dio0); gpio_pad_select_gpio(lmic_pins.dio0);
gpio_set_direction(lmic_pins.dio0, GPIO_MODE_INPUT); gpio_set_direction((gpio_num_t)lmic_pins.dio0, GPIO_MODE_INPUT);
gpio_set_intr_type(lmic_pins.dio0, GPIO_INTR_POSEDGE); gpio_set_intr_type((gpio_num_t)lmic_pins.dio0, GPIO_INTR_POSEDGE);
gpio_isr_handler_add(lmic_pins.dio0, dio_irq_handler, (void *)0); gpio_isr_handler_add((gpio_num_t)lmic_pins.dio0, dioIrqHandler, (void *)0);
gpio_pad_select_gpio(lmic_pins.dio1); gpio_pad_select_gpio((gpio_num_t)lmic_pins.dio1);
gpio_set_direction(lmic_pins.dio1, GPIO_MODE_INPUT); gpio_set_direction((gpio_num_t)lmic_pins.dio1, GPIO_MODE_INPUT);
gpio_set_intr_type(lmic_pins.dio1, GPIO_INTR_POSEDGE); gpio_set_intr_type((gpio_num_t)lmic_pins.dio1, GPIO_INTR_POSEDGE);
gpio_isr_handler_add(lmic_pins.dio1, dio_irq_handler, (void *)1); gpio_isr_handler_add((gpio_num_t)lmic_pins.dio1, dioIrqHandler, (void *)1);
ESP_LOGI(TAG, "IO initialized"); ESP_LOGI(TAG, "IO initialized");
} }
@ -105,7 +105,7 @@ void hal_pin_rxtx(u1_t val)
if (lmic_pins.rxtx == LMIC_UNUSED_PIN) if (lmic_pins.rxtx == LMIC_UNUSED_PIN)
return; return;
gpio_set_level(lmic_pins.rxtx, val); gpio_set_level((gpio_num_t)lmic_pins.rxtx, val);
} }
void hal_pin_rst(u1_t val) void hal_pin_rst(u1_t val)
@ -115,41 +115,38 @@ void hal_pin_rst(u1_t val)
if (val == 0 || val == 1) if (val == 0 || val == 1)
{ // drive pin { // drive pin
gpio_set_level(lmic_pins.rst, val); gpio_set_level((gpio_num_t)lmic_pins.rst, val);
gpio_set_direction(lmic_pins.rst, GPIO_MODE_OUTPUT); gpio_set_direction((gpio_num_t)lmic_pins.rst, GPIO_MODE_OUTPUT);
} }
else else
{ // keep pin floating { // keep pin floating
gpio_set_level(lmic_pins.rst, val); gpio_set_level((gpio_num_t)lmic_pins.rst, val);
gpio_set_direction(lmic_pins.rst, GPIO_MODE_INPUT); gpio_set_direction((gpio_num_t)lmic_pins.rst, GPIO_MODE_INPUT);
} }
} }
s1_t hal_getRssiCal (void) { s1_t hal_getRssiCal (void)
{
return lmic_pins.rssi_cal; return lmic_pins.rssi_cal;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// SPI // SPI
static spi_device_handle_t spi_handle; void HAL_ESP32::spiInit()
static spi_transaction_t spi_trx;
static void hal_spi_init()
{ {
// init device // init device
spi_device_interface_config_t spi_device_intf_config = { spi_device_interface_config_t spiConfig;
.mode = 1, memset(&spiConfig, 0, sizeof(spiConfig));
.clock_speed_hz = CONFIG_TTN_SPI_FREQ, spiConfig.mode = 1;
.command_bits = 0, spiConfig.clock_speed_hz = CONFIG_TTN_SPI_FREQ;
.address_bits = 8, spiConfig.command_bits = 0;
.spics_io_num = lmic_pins.nss, spiConfig.address_bits = 8;
.queue_size = 1, spiConfig.spics_io_num = lmic_pins.nss;
.cs_ena_posttrans = 2 spiConfig.queue_size = 1;
}; spiConfig.cs_ena_posttrans = 2;
esp_err_t ret = spi_bus_add_device(lmic_pins.spi_host, &spi_device_intf_config, &spi_handle); esp_err_t ret = spi_bus_add_device(lmic_pins.spi_host, &spiConfig, &spiHandle);
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "SPI initialized"); ESP_LOGI(TAG, "SPI initialized");
@ -157,24 +154,34 @@ static void hal_spi_init()
void hal_spi_write(u1_t cmd, const u1_t *buf, int len) void hal_spi_write(u1_t cmd, const u1_t *buf, int len)
{ {
memset(&spi_trx, 0, sizeof(spi_trx)); ttn_hal.spiWrite(cmd, buf, len);
spi_trx.addr = cmd; }
spi_trx.length = 8 * len;
spi_trx.tx_buffer = buf; void HAL_ESP32::spiWrite(uint8_t cmd, const uint8_t *buf, int len)
esp_err_t err = spi_device_transmit(spi_handle, &spi_trx); {
memset(&spiTransaction, 0, sizeof(spiTransaction));
spiTransaction.addr = cmd;
spiTransaction.length = 8 * len;
spiTransaction.tx_buffer = buf;
esp_err_t err = spi_device_transmit(spiHandle, &spiTransaction);
ESP_ERROR_CHECK(err); ESP_ERROR_CHECK(err);
} }
void hal_spi_read(u1_t cmd, u1_t *buf, int len) void hal_spi_read(u1_t cmd, u1_t *buf, int len)
{
ttn_hal.spiRead(cmd, buf, len);
}
void HAL_ESP32::spiRead(uint8_t cmd, uint8_t *buf, int len)
{ {
memset(buf, 0, len); memset(buf, 0, len);
memset(&spi_trx, 0, sizeof(spi_trx)); memset(&spiTransaction, 0, sizeof(spiTransaction));
spi_trx.addr = cmd; spiTransaction.addr = cmd;
spi_trx.length = 8 * len; spiTransaction.length = 8 * len;
spi_trx.rxlength = 8 * len; spiTransaction.rxlength = 8 * len;
spi_trx.tx_buffer = buf; spiTransaction.tx_buffer = buf;
spi_trx.rx_buffer = buf; spiTransaction.rx_buffer = buf;
esp_err_t err = spi_device_transmit(spi_handle, &spi_trx); esp_err_t err = spi_device_transmit(spiHandle, &spiTransaction);
ESP_ERROR_CHECK(err); ESP_ERROR_CHECK(err);
} }
@ -200,13 +207,9 @@ void hal_spi_read(u1_t cmd, u1_t *buf, int len)
* by 0x100000000. * by 0x100000000.
*/ */
#define OVERRUN_TRESHOLD 0x10000 // approx 10 seconds static const ostime_t OVERRUN_TRESHOLD = 0x10000; // approx 10 seconds
static uint64_t next_timer_event = 0x200000000; void HAL_ESP32::timerInit()
static void IRAM_ATTR hal_timer_irq_handler(void *arg);
static void hal_time_init()
{ {
timer_config_t config = { timer_config_t config = {
.alarm_en = false, .alarm_en = false,
@ -218,13 +221,13 @@ static void hal_time_init()
}; };
timer_init(TTN_TIMER_GROUP, TTN_TIMER, &config); timer_init(TTN_TIMER_GROUP, TTN_TIMER, &config);
timer_set_counter_value(TTN_TIMER_GROUP, TTN_TIMER, 0x0); timer_set_counter_value(TTN_TIMER_GROUP, TTN_TIMER, 0x0);
timer_isr_register(TTN_TIMER_GROUP, TTN_TIMER, hal_timer_irq_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); timer_isr_register(TTN_TIMER_GROUP, TTN_TIMER, timerIrqHandler, NULL, ESP_INTR_FLAG_IRAM, NULL);
timer_start(TTN_TIMER_GROUP, TTN_TIMER); timer_start(TTN_TIMER_GROUP, TTN_TIMER);
ESP_LOGI(TAG, "Timer initialized"); ESP_LOGI(TAG, "Timer initialized");
} }
static void hal_prepare_next_alarm(u4_t time) void HAL_ESP32::prepareNextAlarm(u4_t time)
{ {
uint64_t now; uint64_t now;
timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now); timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now);
@ -239,74 +242,65 @@ static void hal_prepare_next_alarm(u4_t time)
timer_start(TTN_TIMER_GROUP, TTN_TIMER); timer_start(TTN_TIMER_GROUP, TTN_TIMER);
} }
next_timer_event = time; nextTimerEvent = time;
if (now32 > time && now32 - time > OVERRUN_TRESHOLD) if (now32 > time && now32 - time > OVERRUN_TRESHOLD)
next_timer_event += 0x100000000; nextTimerEvent += 0x100000000;
} }
static void hal_arm_timer() void HAL_ESP32::armTimer()
{ {
timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_DIS); timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_DIS);
timer_set_alarm_value(TTN_TIMER_GROUP, TTN_TIMER, next_timer_event); timer_set_alarm_value(TTN_TIMER_GROUP, TTN_TIMER, nextTimerEvent);
timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_EN); timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_EN);
} }
static void hal_disarm_timer() void HAL_ESP32::disarmTimer()
{ {
timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_DIS); timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_DIS);
next_timer_event = 0x200000000; // wait indefinitely (almost) nextTimerEvent = 0x200000000; // wait indefinitely (almost)
} }
static void IRAM_ATTR hal_timer_irq_handler(void *arg) void IRAM_ATTR HAL_ESP32::timerIrqHandler(void *arg)
{ {
TTN_CLEAR_TIMER_ALARM; TTN_CLEAR_TIMER_ALARM;
BaseType_t higher_prio_task_woken = pdFALSE; BaseType_t higherPrioTaskWoken = pdFALSE;
queue_item_t item = { HALQueueItem item { TIMER };
.ev = TIMER xQueueSendFromISR(ttn_hal.dioQueue, &item, &higherPrioTaskWoken);
}; if (higherPrioTaskWoken)
xQueueSendFromISR(dio_queue, &item, &higher_prio_task_woken);
if (higher_prio_task_woken)
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }
typedef enum { bool HAL_ESP32::wait(WaitKind waitKind)
CHECK_IO,
WAIT_FOR_ANY_EVENT,
WAIT_FOR_TIMER
} wait_open_e;
static bool hal_wait(wait_open_e wait_option)
{ {
TickType_t ticks_to_wait = wait_option == CHECK_IO ? 0 : portMAX_DELAY; TickType_t ticksToWait = waitKind == CHECK_IO ? 0 : portMAX_DELAY;
while (true) while (true)
{ {
queue_item_t item; HALQueueItem item;
if (xQueueReceive(dio_queue, &item, ticks_to_wait) == pdFALSE) if (xQueueReceive(dioQueue, &item, ticksToWait) == pdFALSE)
return false; return false;
if (item.ev == WAKEUP) if (item.ev == WAKEUP)
{ {
if (wait_option != WAIT_FOR_TIMER) if (waitKind != WAIT_FOR_TIMER)
{ {
hal_disarm_timer(); disarmTimer();
return true; return true;
} }
} }
else if (item.ev == TIMER) else if (item.ev == TIMER)
{ {
hal_disarm_timer(); disarmTimer();
if (wait_option != CHECK_IO) if (waitKind != CHECK_IO)
return true; return true;
} }
else // IO interrupt else // IO interrupt
{ {
if (wait_option != WAIT_FOR_TIMER) if (waitKind != WAIT_FOR_TIMER)
hal_disarm_timer(); disarmTimer();
hal_enterCriticalSection(); enterCriticalSection();
radio_irq_handler_v2(item.ev, item.time); radio_irq_handler_v2(item.ev, item.time);
hal_leaveCriticalSection(); leaveCriticalSection();
if (wait_option != WAIT_FOR_TIMER) if (waitKind != WAIT_FOR_TIMER)
return true; return true;
} }
} }
@ -321,21 +315,29 @@ u4_t hal_ticks()
void hal_waitUntil(u4_t time) void hal_waitUntil(u4_t time)
{ {
hal_prepare_next_alarm(time); ttn_hal.waitUntil(time);
hal_arm_timer();
hal_wait(WAIT_FOR_TIMER);
} }
void hal_wakeUp() void HAL_ESP32::waitUntil(uint32_t time)
{ {
queue_item_t item = { prepareNextAlarm(time);
.ev = WAKEUP armTimer();
}; wait(WAIT_FOR_TIMER);
xQueueSend(dio_queue, &item, 0); }
void HAL_ESP32::wakeUp()
{
HALQueueItem item { WAKEUP };
xQueueSend(dioQueue, &item, 0);
} }
// check and rewind for target time // check and rewind for target time
u1_t hal_checkTimer(u4_t time) u1_t hal_checkTimer(u4_t time)
{
return ttn_hal.checkTimer(time);
}
uint8_t HAL_ESP32::checkTimer(uint32_t time)
{ {
uint64_t now; uint64_t now;
timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now); timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now);
@ -352,19 +354,25 @@ u1_t hal_checkTimer(u4_t time)
return 1; // timer has expired recently return 1; // timer has expired recently
} }
hal_prepare_next_alarm(time); prepareNextAlarm(time);
return 0; return 0;
} }
void hal_sleep() void hal_sleep()
{ {
if (hal_wait(CHECK_IO)) ttn_hal.sleep();
}
void HAL_ESP32::sleep()
{
if (wait(CHECK_IO))
return; return;
hal_arm_timer(); armTimer();
hal_wait(WAIT_FOR_ANY_EVENT); wait(WAIT_FOR_ANY_EVENT);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// IRQ // IRQ
@ -380,44 +388,48 @@ void hal_enableIRQs()
// and don't access any shared data structures // and don't access any shared data structures
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Synchronization between application code and background task // Synchronization between application code and background task
static SemaphoreHandle_t mutex; void HAL_ESP32::initCriticalSection()
void hal_initCriticalSection()
{ {
mutex = xSemaphoreCreateRecursiveMutex(); mutex = xSemaphoreCreateRecursiveMutex();
} }
void hal_enterCriticalSection() void HAL_ESP32::enterCriticalSection()
{ {
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
} }
void hal_leaveCriticalSection() void HAL_ESP32::leaveCriticalSection()
{ {
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static void hal_bgTask(void* pvParameter) { void HAL_ESP32::backgroundTask(void* pvParameter) {
os_runloop(); os_runloop();
} }
void hal_init_ex(const void *pContext) void hal_init_ex(const void *pContext)
{ {
// configure radio I/O and interrupt handler ttn_hal.init();
hal_io_init();
// configure radio SPI
hal_spi_init();
// configure timer and interrupt handler
hal_time_init();
} }
void hal_startBgTask() { void HAL_ESP32::init()
xTaskCreate(hal_bgTask, "ttn_lora_task", 1024 * 4, NULL, CONFIG_TTN_BG_TASK_PRIO, NULL); {
// configure radio I/O and interrupt handler
ioInit();
// configure radio SPI
spiInit();
// configure timer and interrupt handler
timerInit();
}
void HAL_ESP32::startBackgroundTask() {
xTaskCreate(backgroundTask, "ttn_lora_task", 1024 * 4, NULL, CONFIG_TTN_BG_TASK_PRIO, NULL);
} }
void hal_failed(const char *file, u2_t line) void hal_failed(const char *file, u2_t line)

View File

@ -14,13 +14,13 @@
#define _hal_esp32_h_ #define _hal_esp32_h_
#include <stdint.h> #include <stdint.h>
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include "driver/spi_master.h" #include "driver/spi_master.h"
#ifdef __cplusplus
extern "C" { extern "C" {
#endif
typedef struct lmic_pinmap { typedef struct lmic_pinmap {
spi_host_device_t spi_host; spi_host_device_t spi_host;
uint8_t nss; uint8_t nss;
uint8_t rxtx; uint8_t rxtx;
@ -28,19 +28,67 @@ typedef struct lmic_pinmap {
uint8_t dio0; uint8_t dio0;
uint8_t dio1; uint8_t dio1;
int8_t rssi_cal; // cal in dB -- added to RSSI measured prior to decision. Must include noise guardband! int8_t rssi_cal; // cal in dB -- added to RSSI measured prior to decision. Must include noise guardband!
} lmic_pinmap; } lmic_pinmap;
extern lmic_pinmap lmic_pins; extern lmic_pinmap lmic_pins;
void hal_startBgTask();
void hal_wakeUp();
void hal_initCriticalSection();
void hal_enterCriticalSection();
void hal_leaveCriticalSection();
#ifdef __cplusplus
} }
#endif
enum HAL_Event {
DIO0 = 0,
DIO1,
DIO2,
TIMER,
WAKEUP
};
enum WaitKind {
CHECK_IO,
WAIT_FOR_ANY_EVENT,
WAIT_FOR_TIMER
};
class HAL_ESP32
{
public:
HAL_ESP32();
void init();
void startBackgroundTask();
void wakeUp();
void initCriticalSection();
void enterCriticalSection();
void leaveCriticalSection();
void spiWrite(uint8_t cmd, const uint8_t *buf, int len);
void spiRead(uint8_t cmd, uint8_t *buf, int len);
uint8_t checkTimer(uint32_t time);
void sleep();
void waitUntil(uint32_t time);
private:
static void backgroundTask(void* pvParameter);
static void dioIrqHandler(void* arg);
void ioInit();
void spiInit();
void timerInit();
void prepareNextAlarm(uint32_t time);
void armTimer();
void disarmTimer();
static void IRAM_ATTR timerIrqHandler(void *arg);
bool wait(WaitKind waitKind);
QueueHandle_t dioQueue;
spi_device_handle_t spiHandle;
spi_transaction_t spiTransaction;
uint64_t nextTimerEvent;
SemaphoreHandle_t mutex;
};
extern HAL_ESP32 ttn_hal;
#endif // _hal_esp32_h_ #endif // _hal_esp32_h_