diff --git a/CMakeLists.txt b/CMakeLists.txt index 6898b00..e01365a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1 +1 @@ -idf_component_register(SRCS "zh_rf24.c" INCLUDE_DIRS "include" REQUIRES driver) \ No newline at end of file +idf_component_register(SRCS "zh_rf24.c" INCLUDE_DIRS "include" REQUIRES driver esp_event) \ No newline at end of file diff --git a/include/zh_rf24.h b/include/zh_rf24.h index 48c9127..247bff5 100644 --- a/include/zh_rf24.h +++ b/include/zh_rf24.h @@ -14,6 +14,7 @@ #include "esp_heap_caps.h" #include "driver/spi_master.h" #include "driver/gpio.h" +#include "esp_event.h" /** * @brief Unique identifier of RF24 interface events base. Used when registering the event handler. @@ -44,7 +45,7 @@ .rx_pipe_3_address = 0xC4, \ .rx_pipe_4_address = 0xC5, \ .rx_pipe_5_address = 0xC6, \ - .task_priority = 4, \ + .task_priority = 3, \ .stack_size = 2048, \ .queue_size = 16 \ } @@ -54,6 +55,27 @@ extern "C" { #endif + typedef enum + { + ZH_RF24_PA_MIN, + ZH_RF24_PA_LOW, + ZH_RF24_PA_HIGH, + ZH_RF24_PA_MAX, + } __attribute__((packed)) zh_rf24_pa_level_t; + + typedef enum + { + ZH_RF24_1MBPS, + ZH_RF24_2MBPS, + ZH_RF24_250KBPS + } __attribute__((packed)) zh_rf24_data_rate_t; + + typedef enum + { + ZH_RF24_TRANSMITTER, + ZH_RF24_RECEIVER + } __attribute__((packed)) zh_rf24_work_mode_t; + /** * @brief Structure for initial initialization of RF24 interface. * @@ -91,42 +113,6 @@ extern "C" ESP_EVENT_DECLARE_BASE(ESP_EVENT_BASE); /// \endcond - /** - * Power Amplifier level. - * - * For use with setPALevel() - */ - typedef enum - { - ZH_RF24_PA_MIN, - ZH_RF24_PA_LOW, - ZH_RF24_PA_HIGH, - ZH_RF24_PA_MAX, - } __attribute__((packed)) zh_rf24_pa_level_t; - - /** - * Data rate. How fast data moves through the air. - * - * For use with setDataRate() - */ - typedef enum - { - ZH_RF24_1MBPS, - ZH_RF24_2MBPS, - ZH_RF24_250KBPS - } __attribute__((packed)) zh_rf24_data_rate_t; - - /** - * CRC Length. How big (if any) of a CRC is included. - * - * For use with setCRCLength() - */ - typedef enum - { - ZH_RF24_TRANSMITTER, - ZH_RF24_RECEIVER - } __attribute__((packed)) zh_rf24_work_mode_t; - /** * @brief Enumeration of possible RF24 events. * diff --git a/zh_rf24.c b/zh_rf24.c index ae39c61..558678c 100644 --- a/zh_rf24.c +++ b/zh_rf24.c @@ -9,17 +9,21 @@ #define ZH_RF24_DATA_SEND_SUCCESS BIT0 #define ZH_RF24_DATA_SEND_FAIL BIT1 #define ZH_RF24_MAX_MESSAGE_SIZE 32 +#define ZH_SPI_HOST SPI2_HOST /// \endcond static void s_zh_rf24_processing(void *pvParameter); +static void s_zh_rf24_irq_isr_handler(void *arg); +static void s_zh_rf24_irq_processing_task(void *pvParameter); static const char *TAG = "zh_rf24"; static EventGroupHandle_t s_zh_rf24_send_cb_status_event_group_handle = {0}; static QueueHandle_t s_zh_rf24_queue_handle = {0}; static TaskHandle_t s_zh_rf24_processing_task_handle = {0}; +static SemaphoreHandle_t s_zh_rf24_irq_semaphore = {0}; static zh_rf24_init_config_t s_zh_rf24_init_config = {0}; -static spi_device_handle_t s_zh_spi_device_handle = {0}; +static spi_device_handle_t s_zh_rf24_spi_handle = {0}; static bool s_zh_rf24_is_initialized = false; /// \cond @@ -32,6 +36,7 @@ typedef enum typedef struct { uint8_t pipe; + bool confirm; uint8_t *data; uint8_t data_len; } __attribute__((packed)) zh_rf24_queue_data_t; @@ -56,17 +61,111 @@ esp_err_t zh_rf24_init(zh_rf24_init_config_t *config) s_zh_rf24_init_config = *config; s_zh_rf24_send_cb_status_event_group_handle = xEventGroupCreate(); s_zh_rf24_queue_handle = xQueueCreate(s_zh_rf24_init_config.queue_size, sizeof(zh_rf24_queue_t)); - // if (esp_now_init() != ESP_OK || esp_now_register_send_cb(s_zh_espnow_send_cb) != ESP_OK || esp_now_register_recv_cb(s_zh_espnow_recv_cb) != ESP_OK) - // { - // ESP_LOGE(TAG, "ESP-NOW initialization fail. Internal error."); - // return ESP_FAIL; - // } - // if (xTaskCreatePinnedToCore(&s_zh_espnow_processing, "NULL", s_zh_espnow_init_config.stack_size, NULL, s_zh_espnow_init_config.task_priority, &s_zh_espnow_processing_task_handle, tskNO_AFFINITY) != pdPASS) - // { - // ESP_LOGE(TAG, "ESP-NOW initialization fail. Internal error."); - // return ESP_FAIL; - // } + gpio_config_t pin_config = {0}; + pin_config.intr_type = GPIO_INTR_DISABLE; + pin_config.mode = GPIO_MODE_OUTPUT; + pin_config.pin_bit_mask = (1ULL << s_zh_rf24_init_config.ce_pin); + pin_config.pull_down_en = GPIO_PULLDOWN_DISABLE; + pin_config.pull_up_en = GPIO_PULLUP_DISABLE; + if (gpio_config(&pin_config) != ESP_OK) + { + ESP_LOGE(TAG, "RF24 initialization fail. Incorrect GPIO number."); + return ESP_ERR_INVALID_ARG; + } + gpio_set_level(s_zh_rf24_init_config.ce_pin, 0); + pin_config.intr_type = GPIO_INTR_DISABLE; + pin_config.mode = GPIO_MODE_OUTPUT; + pin_config.pin_bit_mask = (1ULL << s_zh_rf24_init_config.csn_pin); + pin_config.pull_down_en = GPIO_PULLDOWN_DISABLE; + pin_config.pull_up_en = GPIO_PULLUP_DISABLE; + if (gpio_config(&pin_config) != ESP_OK) + { + ESP_LOGE(TAG, "RF24 initialization fail. Incorrect GPIO number."); + return ESP_ERR_INVALID_ARG; + } + gpio_set_level(s_zh_rf24_init_config.csn_pin, 1); + pin_config.intr_type = GPIO_INTR_NEGEDGE; + pin_config.mode = GPIO_MODE_INPUT; + pin_config.pin_bit_mask = (1ULL << s_zh_rf24_init_config.irq_pin); + pin_config.pull_down_en = GPIO_PULLDOWN_DISABLE; + pin_config.pull_up_en = GPIO_PULLUP_ENABLE; + if (gpio_config(&pin_config) != ESP_OK) + { + ESP_LOGE(TAG, "RF24 initialization fail. Incorrect GPIO number."); + return ESP_ERR_INVALID_ARG; + } + spi_bus_config_t spi_bus_config = { + .sclk_io_num = s_zh_rf24_init_config.sck_pin, + .mosi_io_num = s_zh_rf24_init_config.mosi_pin, + .miso_io_num = s_zh_rf24_init_config.miso_pin, + .quadwp_io_num = -1, + .quadhd_io_num = -1}; + if (spi_bus_initialize(ZH_SPI_HOST, &spi_bus_config, SPI_DMA_CH_AUTO) != ESP_OK) + { + ESP_LOGE(TAG, "RF24 initialization fail. SPI initialization error."); + return ESP_FAIL; + } + spi_device_interface_config_t spi_device_interface_config = { + .clock_speed_hz = 4000000, + .spics_io_num = -1, + .queue_size = 7, + .mode = 0, + .flags = SPI_DEVICE_NO_DUMMY}; + if (spi_bus_add_device(ZH_SPI_HOST, &spi_device_interface_config, &s_zh_rf24_spi_handle) != ESP_OK) + { + ESP_LOGE(TAG, "RF24 initialization fail. SPI initialization error."); + return ESP_FAIL; + } + s_zh_rf24_irq_semaphore = xSemaphoreCreateBinary(); + if (gpio_install_isr_service(0) != ESP_OK || gpio_isr_handler_add(s_zh_rf24_init_config.irq_pin, s_zh_rf24_irq_isr_handler, NULL) != ESP_OK) + { + ESP_LOGE(TAG, "RF24 initialization fail. Internal error."); + return ESP_FAIL; + } + if (xTaskCreatePinnedToCore(&s_zh_rf24_irq_processing_task, "NULL", s_zh_rf24_init_config.stack_size, NULL, s_zh_rf24_init_config.task_priority, NULL, tskNO_AFFINITY) != pdPASS) + { + ESP_LOGE(TAG, "RF24 initialization fail. Internal error."); + return ESP_FAIL; + } s_zh_rf24_is_initialized = true; ESP_LOGI(TAG, "RF24 initialization success."); return ESP_OK; +} + +esp_err_t zh_rf24_deinit(void) +{ + return 0; +} + +esp_err_t zh_rf24_send(const uint8_t *data, const uint8_t data_len, const bool confirm) +{ + return 0; +} + +static void s_zh_rf24_processing(void *pvParameter) +{ +} + +static void s_zh_rf24_irq_isr_handler(void *arg) +{ + xSemaphoreGiveFromISR(s_zh_rf24_irq_semaphore, NULL); +} + +static void s_zh_rf24_irq_processing_task(void *pvParameter) +{ + for (;;) + { + xSemaphoreTake(s_zh_rf24_irq_semaphore, portMAX_DELAY); + // switch_config->gpio_processing = true; + // switch_config->status.status = (switch_config->status.status == HAONOFT_ON) ? HAONOFT_OFF : HAONOFT_ON; + // zh_gpio_set_level(switch_config); + // zh_save_status(switch_config); + // if (switch_config->gateway_is_available == true) + // { + // zh_send_switch_status_message(switch_config); + // } + // vTaskDelay(500 / portTICK_PERIOD_MS); // To prevent button contact rattling. Value is selected experimentally. + // switch_config->gpio_processing = false; + } + vTaskDelete(NULL); } \ No newline at end of file