This commit is contained in:
Alexey Zholtikov 2024-05-15 13:38:12 +03:00
parent 6a1cc5713e
commit bc848c297d
3 changed files with 134 additions and 49 deletions

View File

@ -1 +1 @@
idf_component_register(SRCS "zh_rf24.c" INCLUDE_DIRS "include" REQUIRES driver)
idf_component_register(SRCS "zh_rf24.c" INCLUDE_DIRS "include" REQUIRES driver esp_event)

View File

@ -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.
*

121
zh_rf24.c
View File

@ -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);
}