6
This commit is contained in:
parent
9a668b759e
commit
24b2579fd4
352
zh_rf24.c
352
zh_rf24.c
@ -6,10 +6,10 @@
|
||||
#include "zh_rf24.h"
|
||||
|
||||
/// \cond
|
||||
#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
|
||||
#define DATA_SEND_SUCCESS BIT0
|
||||
#define DATA_SEND_FAIL BIT1
|
||||
#define MAX_MESSAGE_SIZE 32
|
||||
#define SPI_HOST SPI2_HOST
|
||||
/// \endcond
|
||||
|
||||
/* Команды */
|
||||
@ -83,65 +83,65 @@
|
||||
#define ERX_P0 0 // Включает канал 0 приёмника
|
||||
|
||||
// SETUP_AW
|
||||
#define AW 0 // Два бита, Выбирает ширину поля адреса: 1 - 3 байта; 2 - 4 байта; 3 - 5 байт.
|
||||
// #define AW 0 // Два бита, Выбирает ширину поля адреса: 1 - 3 байта; 2 - 4 байта; 3 - 5 байт.
|
||||
|
||||
#define SETUP_AW_3BYTES_ADDRESS (1 << AW)
|
||||
#define SETUP_AW_4BYTES_ADDRESS (2 << AW)
|
||||
#define SETUP_AW_5BYTES_ADDRESS (3 << AW)
|
||||
// #define SETUP_AW_3BYTES_ADDRESS (1 << AW)
|
||||
// #define SETUP_AW_4BYTES_ADDRESS (2 << AW)
|
||||
// #define SETUP_AW_5BYTES_ADDRESS (3 << AW)
|
||||
|
||||
// SETUP_RETR
|
||||
#define ARD 4 // 4 бита. Задаёт значение задержки перед повторной отправкой пакета: 250 x (n + 1) мкс
|
||||
#define ARC 0 // 4 битай. Количество повторных попыток отправки, 0 - повторная отправка отключена.
|
||||
|
||||
#define SETUP_RETR_DELAY_250MKS (0 << ARD)
|
||||
#define SETUP_RETR_DELAY_500MKS (1 << ARD)
|
||||
#define SETUP_RETR_DELAY_750MKS (2 << ARD)
|
||||
#define SETUP_RETR_DELAY_1000MKS (3 << ARD)
|
||||
#define SETUP_RETR_DELAY_1250MKS (4 << ARD)
|
||||
#define SETUP_RETR_DELAY_1500MKS (5 << ARD)
|
||||
#define SETUP_RETR_DELAY_1750MKS (6 << ARD)
|
||||
#define SETUP_RETR_DELAY_2000MKS (7 << ARD)
|
||||
#define SETUP_RETR_DELAY_2250MKS (8 << ARD)
|
||||
#define SETUP_RETR_DELAY_2500MKS (9 << ARD)
|
||||
#define SETUP_RETR_DELAY_2750MKS (10 << ARD)
|
||||
#define SETUP_RETR_DELAY_3000MKS (11 << ARD)
|
||||
#define SETUP_RETR_DELAY_3250MKS (12 << ARD)
|
||||
#define SETUP_RETR_DELAY_3500MKS (13 << ARD)
|
||||
#define SETUP_RETR_DELAY_3750MKS (14 << ARD)
|
||||
#define SETUP_RETR_DELAY_4000MKS (15 << ARD)
|
||||
// #define SETUP_RETR_DELAY_250MKS (0 << ARD)
|
||||
// #define SETUP_RETR_DELAY_500MKS (1 << ARD)
|
||||
// #define SETUP_RETR_DELAY_750MKS (2 << ARD)
|
||||
// #define SETUP_RETR_DELAY_1000MKS (3 << ARD)
|
||||
// #define SETUP_RETR_DELAY_1250MKS (4 << ARD)
|
||||
// #define SETUP_RETR_DELAY_1500MKS (5 << ARD)
|
||||
// #define SETUP_RETR_DELAY_1750MKS (6 << ARD)
|
||||
// #define SETUP_RETR_DELAY_2000MKS (7 << ARD)
|
||||
// #define SETUP_RETR_DELAY_2250MKS (8 << ARD)
|
||||
// #define SETUP_RETR_DELAY_2500MKS (9 << ARD)
|
||||
// #define SETUP_RETR_DELAY_2750MKS (10 << ARD)
|
||||
// #define SETUP_RETR_DELAY_3000MKS (11 << ARD)
|
||||
// #define SETUP_RETR_DELAY_3250MKS (12 << ARD)
|
||||
// #define SETUP_RETR_DELAY_3500MKS (13 << ARD)
|
||||
// #define SETUP_RETR_DELAY_3750MKS (14 << ARD)
|
||||
// #define SETUP_RETR_DELAY_4000MKS (15 << ARD)
|
||||
|
||||
#define SETUP_RETR_NO_RETRANSMIT (0 << ARC)
|
||||
#define SETUP_RETR_UP_TO_1_RETRANSMIT (1 << ARC)
|
||||
#define SETUP_RETR_UP_TO_2_RETRANSMIT (2 << ARC)
|
||||
#define SETUP_RETR_UP_TO_3_RETRANSMIT (3 << ARC)
|
||||
#define SETUP_RETR_UP_TO_4_RETRANSMIT (4 << ARC)
|
||||
#define SETUP_RETR_UP_TO_5_RETRANSMIT (5 << ARC)
|
||||
#define SETUP_RETR_UP_TO_6_RETRANSMIT (6 << ARC)
|
||||
#define SETUP_RETR_UP_TO_7_RETRANSMIT (7 << ARC)
|
||||
#define SETUP_RETR_UP_TO_8_RETRANSMIT (8 << ARC)
|
||||
#define SETUP_RETR_UP_TO_9_RETRANSMIT (9 << ARC)
|
||||
#define SETUP_RETR_UP_TO_10_RETRANSMIT (10 << ARC)
|
||||
#define SETUP_RETR_UP_TO_11_RETRANSMIT (11 << ARC)
|
||||
#define SETUP_RETR_UP_TO_12_RETRANSMIT (12 << ARC)
|
||||
#define SETUP_RETR_UP_TO_13_RETRANSMIT (13 << ARC)
|
||||
#define SETUP_RETR_UP_TO_14_RETRANSMIT (14 << ARC)
|
||||
#define SETUP_RETR_UP_TO_15_RETRANSMIT (15 << ARC)
|
||||
// #define SETUP_RETR_NO_RETRANSMIT (0 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_1_RETRANSMIT (1 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_2_RETRANSMIT (2 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_3_RETRANSMIT (3 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_4_RETRANSMIT (4 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_5_RETRANSMIT (5 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_6_RETRANSMIT (6 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_7_RETRANSMIT (7 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_8_RETRANSMIT (8 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_9_RETRANSMIT (9 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_10_RETRANSMIT (10 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_11_RETRANSMIT (11 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_12_RETRANSMIT (12 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_13_RETRANSMIT (13 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_14_RETRANSMIT (14 << ARC)
|
||||
// #define SETUP_RETR_UP_TO_15_RETRANSMIT (15 << ARC)
|
||||
|
||||
// RF_SETUP
|
||||
#define CONT_WAVE 7 // (Только для nRF24L01+) Непрерывная передача несущей (для тестов)
|
||||
#define RF_DR_LOW 5 // (Только для nRF24L01+) Включает скорость 250кбит/с. RF_DR_HIGH должен быть 0
|
||||
#define PLL_LOCK 4 // Для тестов
|
||||
#define RF_DR_HIGH 3 // Выбор скорости обмена (при значении бита RF_DR_LOW = 0): 0 - 1Мбит/с; 1 - 2Мбит/с
|
||||
#define RF_PWR 1 // 2бита. Выбирает мощность передатчика: 0 - -18dBm; 1 - -16dBm; 2 - -6dBm; 3 - 0dBm
|
||||
// #define CONT_WAVE 7 // (Только для nRF24L01+) Непрерывная передача несущей (для тестов)
|
||||
// #define RF_DR_LOW 5 // (Только для nRF24L01+) Включает скорость 250кбит/с. RF_DR_HIGH должен быть 0
|
||||
// #define PLL_LOCK 4 // Для тестов
|
||||
// #define RF_DR_HIGH 3 // Выбор скорости обмена (при значении бита RF_DR_LOW = 0): 0 - 1Мбит/с; 1 - 2Мбит/с
|
||||
// #define RF_PWR 1 // 2бита. Выбирает мощность передатчика: 0 - -18dBm; 1 - -16dBm; 2 - -6dBm; 3 - 0dBm
|
||||
|
||||
#define RF_SETUP_MINUS18DBM (0 << RF_PWR)
|
||||
#define RF_SETUP_MINUS12DBM (1 << RF_PWR)
|
||||
#define RF_SETUP_MINUS6DBM (2 << RF_PWR)
|
||||
#define RF_SETUP_0DBM (3 << RF_PWR)
|
||||
// #define RF_SETUP_MINUS18DBM (0 << RF_PWR)
|
||||
// #define RF_SETUP_MINUS12DBM (1 << RF_PWR)
|
||||
// #define RF_SETUP_MINUS6DBM (2 << RF_PWR)
|
||||
// #define RF_SETUP_0DBM (3 << RF_PWR)
|
||||
|
||||
#define RF_SETUP_1MBPS (0 << RF_DR_HIGH)
|
||||
#define RF_SETUP_2MBPS (1 << RF_DR_HIGH)
|
||||
#define RF_SETUP_250KBPS (1 << RF_DR_LOW) // этот режим не должен использоваться с контролем доставки
|
||||
// #define RF_SETUP_1MBPS (0 << RF_DR_HIGH)
|
||||
// #define RF_SETUP_2MBPS (1 << RF_DR_HIGH)
|
||||
// #define RF_SETUP_250KBPS (1 << RF_DR_LOW) // этот режим не должен использоваться с контролем доставки
|
||||
|
||||
// STATUS
|
||||
#define RX_DR 6 // Флаг получения новых данных в FIFO приёмника. Для сброса флага нужно записать 1
|
||||
@ -152,8 +152,8 @@
|
||||
// (переименовано из TX_FULL во избежание путаницы с одноимённым битом из регистра FIFO_STATUS)
|
||||
|
||||
// OBSERVE_TX
|
||||
#define PLOS_CNT 4 // 4 бита. Общее количество пакетов без подтверждения. Сбрасывается записью RF_CH
|
||||
#define ARC_CNT 0 // 4 бита. Количество предпринятых повторов при последней отправке.
|
||||
// #define PLOS_CNT 4 // 4 бита. Общее количество пакетов без подтверждения. Сбрасывается записью RF_CH
|
||||
// #define ARC_CNT 0 // 4 бита. Количество предпринятых повторов при последней отправке.
|
||||
|
||||
// FIFO_STATUS
|
||||
#define TX_REUSE 6 // Признак готовности последнего пакета для повторной отправки.
|
||||
@ -176,44 +176,44 @@
|
||||
#define EN_ACK_PAY 1 // Разрешает передачу данных с пакетами подтверждения приёма
|
||||
#define EN_DYN_ACK 0 // Разрешает использование W_TX_PAYLOAD_NOACK
|
||||
|
||||
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(void *pvParameter);
|
||||
static void s_zh_rf24_read_register(const uint8_t *reg, uint8_t *value, const uint8_t length);
|
||||
static void s_zh_rf24_write_register(const uint8_t *reg, uint8_t *value, const uint8_t length);
|
||||
static void s_zh_rf24_read_data(uint8_t *data, const uint8_t length);
|
||||
static void s_zh_rf24_write_data(uint8_t *data, const uint8_t length);
|
||||
static uint8_t s_zh_rf24_send_command(uint8_t *command);
|
||||
static void _processing(void *pvParameter);
|
||||
static void _irq_isr_handler(void *arg);
|
||||
static void _irq_processing(void *pvParameter);
|
||||
static void _read_register(const uint8_t *reg, uint8_t *value, const uint8_t length);
|
||||
static void _write_register(const uint8_t *reg, uint8_t *value, const uint8_t length);
|
||||
static void _read_data(uint8_t *data, const uint8_t length);
|
||||
static void _write_data(uint8_t *data, const uint8_t length);
|
||||
static uint8_t _send_command(uint8_t *command);
|
||||
|
||||
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_rf24_spi_handle = {0};
|
||||
static bool s_zh_rf24_is_initialized = false;
|
||||
static EventGroupHandle_t _send_cb_status_event_group_handle = {0};
|
||||
static QueueHandle_t _queue_handle = {0};
|
||||
static TaskHandle_t _processing_task_handle = {0};
|
||||
static SemaphoreHandle_t _irq_semaphore = {0};
|
||||
static zh_rf24_init_config_t _init_config = {0};
|
||||
static spi_device_handle_t _spi_handle = {0};
|
||||
static bool _is_initialized = false;
|
||||
|
||||
/// \cond
|
||||
typedef enum
|
||||
{
|
||||
ZH_RF24_RECV,
|
||||
ZH_RF24_SEND,
|
||||
} __attribute__((packed)) zh_rf24_queue_id_t;
|
||||
ON_RECV,
|
||||
TO_SEND,
|
||||
} __attribute__((packed)) queue_id_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe;
|
||||
uint8_t *data;
|
||||
uint8_t data_len;
|
||||
} __attribute__((packed)) zh_rf24_queue_data_t;
|
||||
} __attribute__((packed)) queue_data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
zh_rf24_queue_id_t id;
|
||||
zh_rf24_queue_data_t data;
|
||||
} __attribute__((packed)) zh_rf24_queue_t;
|
||||
queue_id_t id;
|
||||
queue_data_t data;
|
||||
} __attribute__((packed)) queue_t;
|
||||
|
||||
ESP_EVENT_DEFINE_BASE(ZH_RF24);
|
||||
/// \endcond
|
||||
@ -226,13 +226,13 @@ esp_err_t zh_rf24_init(zh_rf24_init_config_t *config)
|
||||
ESP_LOGE(TAG, "RF24 initialization fail. Invalid argument.");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
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));
|
||||
_init_config = *config;
|
||||
_send_cb_status_event_group_handle = xEventGroupCreate();
|
||||
_queue_handle = xQueueCreate(_init_config.queue_size, sizeof(queue_t));
|
||||
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.pin_bit_mask = (1ULL << _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)
|
||||
@ -240,10 +240,10 @@ esp_err_t zh_rf24_init(zh_rf24_init_config_t *config)
|
||||
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);
|
||||
gpio_set_level(_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.pin_bit_mask = (1ULL << _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)
|
||||
@ -251,10 +251,10 @@ esp_err_t zh_rf24_init(zh_rf24_init_config_t *config)
|
||||
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);
|
||||
gpio_set_level(_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.pin_bit_mask = (1ULL << _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)
|
||||
@ -263,12 +263,12 @@ esp_err_t zh_rf24_init(zh_rf24_init_config_t *config)
|
||||
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,
|
||||
.sclk_io_num = _init_config.sck_pin,
|
||||
.mosi_io_num = _init_config.mosi_pin,
|
||||
.miso_io_num = _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)
|
||||
if (spi_bus_initialize(SPI_HOST, &spi_bus_config, SPI_DMA_CH_AUTO) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "RF24 initialization fail. SPI initialization error.");
|
||||
return ESP_FAIL;
|
||||
@ -279,53 +279,54 @@ esp_err_t zh_rf24_init(zh_rf24_init_config_t *config)
|
||||
.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)
|
||||
if (spi_bus_add_device(SPI_HOST, &spi_device_interface_config, &_spi_handle) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "RF24 initialization fail. SPI initialization error.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
for (uint8_t i = 0; i < 100; ++i)
|
||||
{
|
||||
s_zh_rf24_write_register(CONFIG, (1 << EN_CRC) | (1 << CRCO) | (1 << PRIM_RX), 1);
|
||||
_write_register(CONFIG, (1 << EN_CRC) | (1 << CRCO) | (1 << PRIM_RX), 1);
|
||||
uint8_t value = 0;
|
||||
s_zh_rf24_read_register(CONFIG, &value, 1);
|
||||
_read_register(CONFIG, &value, 1);
|
||||
if (value == ((1 << EN_CRC) | (1 << CRCO) | (1 << PRIM_RX)))
|
||||
{
|
||||
s_zh_rf24_write_register(EN_AA, 0x3F, 1); // Enable auto acknowledgment for all pipes.
|
||||
s_zh_rf24_write_register(EN_RXADDR, 0x3F, 1); // Enable all pipes.
|
||||
s_zh_rf24_write_register(SETUP_AW, 0x03, 1); // Setup address widths for 5 bytes. // выбор длины адреса 5 байт
|
||||
s_zh_rf24_write_register(SETUP_RETR, 0x1F, 1); // Setup automatic retransmission a maximum of 15 times with delay of 500 µs between attempts.
|
||||
s_zh_rf24_write_register(RF_CH, &s_zh_rf24_init_config.channel, 1); // Setup RF channel.
|
||||
s_zh_rf24_write_register(RF_SETUP, 0x06, 1); // Setup data rate 1 Mbps and 0 dBm RF output power in TX mode.
|
||||
s_zh_rf24_write_register(RX_ADDR_P0, &s_zh_rf24_init_config.tx_address, 5); // Setup receive address for pipe 0.
|
||||
s_zh_rf24_write_register(RX_ADDR_P1, &s_zh_rf24_init_config.rx_pipe_1_address, 5); // Setup receive address for pipe 1.
|
||||
s_zh_rf24_write_register(RX_ADDR_P2, &s_zh_rf24_init_config.rx_pipe_2_address, 1); // Setup receive address for pipe 2.
|
||||
s_zh_rf24_write_register(RX_ADDR_P3, &s_zh_rf24_init_config.rx_pipe_3_address, 1); // Setup receive address for pipe 3.
|
||||
s_zh_rf24_write_register(RX_ADDR_P4, &s_zh_rf24_init_config.rx_pipe_4_address, 1); // Setup receive address for pipe 4.
|
||||
s_zh_rf24_write_register(RX_ADDR_P5, &s_zh_rf24_init_config.rx_pipe_5_address, 1); // Setup receive address for pipe 5.
|
||||
s_zh_rf24_write_register(TX_ADDR, &s_zh_rf24_init_config.tx_address, 5); // Setup transmitter address.
|
||||
s_zh_rf24_write_register(RX_PW_P0, 32, 1); // Setup the maximum data length for pipe 0.
|
||||
s_zh_rf24_write_register(RX_PW_P1, 32, 1); // Setup the maximum data length for pipe 1.
|
||||
s_zh_rf24_write_register(RX_PW_P2, 32, 1); // Setup the maximum data length for pipe 2.
|
||||
s_zh_rf24_write_register(RX_PW_P3, 32, 1); // Setup the maximum data length for pipe 3.
|
||||
s_zh_rf24_write_register(RX_PW_P4, 32, 1); // Setup the maximum data length for pipe 4.
|
||||
s_zh_rf24_write_register(RX_PW_P5, 32, 1); // Setup the maximum data length for pipe 5.
|
||||
s_zh_rf24_write_register(FEATURE, 0x04, 1); // Enable dynamic payload length.
|
||||
s_zh_rf24_write_register(DYNPD, 0x3F, 1); // Setup dynamic payload length for all pipes.
|
||||
s_zh_rf24_write_register(CONFIG, (1 << EN_CRC) | (1 << CRCO) | (1 << PWR_UP) | (1 << PRIM_RX), 1);
|
||||
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)
|
||||
_write_register(EN_AA, (1 << ENAA_P5) | (1 << ENAA_P4) | (1 << ENAA_P3) | (1 << ENAA_P2) | (1 << ENAA_P1) | (1 << ENAA_P0), 1); // Enable auto acknowledgment for all pipes.
|
||||
_write_register(EN_RXADDR, (1 << ERX_P5) | (1 << ERX_P4) | (1 << ERX_P3) | (1 << ERX_P2) | (1 << ERX_P1) | (1 << ERX_P0), 1); // Enable all pipes.
|
||||
_write_register(SETUP_AW, 0x03, 1); // Setup address widths for 5 bytes.
|
||||
_write_register(SETUP_RETR, 0x1F, 1); // Setup automatic retransmission a maximum of 15 times with delay of 500 µs between attempts.
|
||||
_write_register(RF_CH, &_init_config.channel, 1); // Setup RF channel.
|
||||
_write_register(RF_SETUP, 0x06, 1); // Setup data rate 1 Mbps and 0 dBm RF output power in TX mode.
|
||||
_write_register(RX_ADDR_P0, &_init_config.tx_address, 5); // Setup receive address for pipe 0.
|
||||
_write_register(RX_ADDR_P1, &_init_config.rx_pipe_1_address, 5); // Setup receive address for pipe 1.
|
||||
_write_register(RX_ADDR_P2, &_init_config.rx_pipe_2_address, 1); // Setup receive address for pipe 2.
|
||||
_write_register(RX_ADDR_P3, &_init_config.rx_pipe_3_address, 1); // Setup receive address for pipe 3.
|
||||
_write_register(RX_ADDR_P4, &_init_config.rx_pipe_4_address, 1); // Setup receive address for pipe 4.
|
||||
_write_register(RX_ADDR_P5, &_init_config.rx_pipe_5_address, 1); // Setup receive address for pipe 5.
|
||||
_write_register(TX_ADDR, &_init_config.tx_address, 5); // Setup transmitter address.
|
||||
_write_register(RX_PW_P0, 32, 1); // Setup the maximum data length for pipe 0.
|
||||
_write_register(RX_PW_P1, 32, 1); // Setup the maximum data length for pipe 1.
|
||||
_write_register(RX_PW_P2, 32, 1); // Setup the maximum data length for pipe 2.
|
||||
_write_register(RX_PW_P3, 32, 1); // Setup the maximum data length for pipe 3.
|
||||
_write_register(RX_PW_P4, 32, 1); // Setup the maximum data length for pipe 4.
|
||||
_write_register(RX_PW_P5, 32, 1); // Setup the maximum data length for pipe 5.
|
||||
_write_register(FEATURE, 0x04, 1); // Enable dynamic payload length.
|
||||
_write_register(DYNPD, 0x3F, 1); // Setup dynamic payload length for all pipes.
|
||||
_write_register(CONFIG, (1 << EN_CRC) | (1 << CRCO) | (1 << PWR_UP) | (1 << PRIM_RX), 1);
|
||||
_irq_semaphore = xSemaphoreCreateBinary();
|
||||
if (gpio_install_isr_service(0) != ESP_OK || gpio_isr_handler_add(_init_config.irq_pin, _irq_isr_handler, NULL) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "RF24 initialization fail. Internal error.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (xTaskCreatePinnedToCore(&s_zh_rf24_irq_processing, "NULL", s_zh_rf24_init_config.stack_size, NULL, s_zh_rf24_init_config.task_priority, NULL, tskNO_AFFINITY) != pdPASS)
|
||||
if (xTaskCreatePinnedToCore(&_irq_processing, "NULL", _init_config.stack_size, NULL, _init_config.task_priority, NULL, tskNO_AFFINITY) != pdPASS ||
|
||||
xTaskCreatePinnedToCore(&_processing, "NULL", _init_config.stack_size, NULL, _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;
|
||||
gpio_set_level(s_zh_rf24_init_config.ce_pin, 1);
|
||||
_is_initialized = true;
|
||||
gpio_set_level(_init_config.ce_pin, 1);
|
||||
ESP_LOGI(TAG, "RF24 initialization success.");
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -343,24 +344,24 @@ esp_err_t zh_rf24_deinit(void)
|
||||
esp_err_t zh_rf24_send(const uint8_t *data, const uint8_t data_len)
|
||||
{
|
||||
ESP_LOGI(TAG, "Adding outgoing RF24 data to queue begin.");
|
||||
if (s_zh_rf24_is_initialized == false)
|
||||
if (_is_initialized == false)
|
||||
{
|
||||
ESP_LOGE(TAG, "Adding outgoing RF24 data to queue fail. RF24 not initialized.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (data == NULL || data_len == 0 || data_len > ZH_RF24_MAX_MESSAGE_SIZE)
|
||||
if (data == NULL || data_len == 0 || data_len > MAX_MESSAGE_SIZE)
|
||||
{
|
||||
ESP_LOGE(TAG, "Adding outgoing RF24 data to queue fail. Invalid argument.");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (uxQueueSpacesAvailable(s_zh_rf24_queue_handle) < s_zh_rf24_init_config.queue_size / 10)
|
||||
if (uxQueueSpacesAvailable(_queue_handle) < _init_config.queue_size / 10)
|
||||
{
|
||||
ESP_LOGW(TAG, "Adding outgoing RF24 data to queue fail. Queue is almost full.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
zh_rf24_queue_t rf24_queue = {0};
|
||||
rf24_queue.id = ZH_RF24_SEND;
|
||||
zh_rf24_queue_data_t *send_data = &rf24_queue.data;
|
||||
queue_t queue = {0};
|
||||
queue.id = TO_SEND;
|
||||
queue_data_t *send_data = &queue.data;
|
||||
if (data_len / sizeof(void *) == 0)
|
||||
{
|
||||
send_data->data = heap_caps_malloc(data_len, MALLOC_CAP_32BIT);
|
||||
@ -371,34 +372,91 @@ esp_err_t zh_rf24_send(const uint8_t *data, const uint8_t data_len)
|
||||
}
|
||||
if (send_data->data == NULL)
|
||||
{
|
||||
ESP_LOGE(TAG, "Adding outgoing ESP-NOW data to queue fail. Memory allocation fail or no free memory in the heap.");
|
||||
ESP_LOGE(TAG, "Adding outgoing RF24 data to queue fail. Memory allocation fail or no free memory in the heap.");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
memset(send_data->data, 0, data_len);
|
||||
memcpy(send_data->data, data, data_len);
|
||||
send_data->data_len = data_len;
|
||||
ESP_LOGI(TAG, "Adding outgoing RF24 data to queue success.");
|
||||
if (xQueueSend(s_zh_rf24_queue_handle, &rf24_queue, portTICK_PERIOD_MS) != pdTRUE)
|
||||
if (xQueueSend(_queue_handle, &queue, portTICK_PERIOD_MS) != pdTRUE)
|
||||
{
|
||||
ESP_LOGE(TAG, "RF24 message processing task internal error.");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void s_zh_rf24_processing(void *pvParameter)
|
||||
static void _processing(void *pvParameter)
|
||||
{
|
||||
queue_t queue = {0};
|
||||
while (xQueueReceive(_queue_handle, &queue, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
switch (queue.id)
|
||||
{
|
||||
case TO_SEND:
|
||||
ESP_LOGI(TAG, "Outgoing RF24 data processing begin.");
|
||||
queue_data_t *send_data = &queue.data;
|
||||
gpio_set_level(_init_config.ce_pin, 0);
|
||||
_write_register(CONFIG, (1 << EN_CRC) | (1 << CRCO) | (1 << PWR_UP), 1);
|
||||
_send_command(FLUSH_TX);
|
||||
_write_data(send_data->data, send_data->data_len);
|
||||
gpio_set_level(_init_config.ce_pin, 1);
|
||||
esp_rom_delay_us(15);
|
||||
gpio_set_level(_init_config.ce_pin, 0);
|
||||
zh_rf24_event_on_send_t *on_send = heap_caps_malloc(sizeof(zh_rf24_event_on_send_t), MALLOC_CAP_8BIT);
|
||||
if (on_send == NULL)
|
||||
{
|
||||
ESP_LOGE(TAG, "Outgoing RF24 data processing fail. Memory allocation fail or no free memory in the heap.");
|
||||
heap_caps_free(send_data->data);
|
||||
heap_caps_free(on_send);
|
||||
break;
|
||||
}
|
||||
EventBits_t bit = xEventGroupWaitBits(_send_cb_status_event_group_handle, DATA_SEND_SUCCESS | DATA_SEND_FAIL, pdTRUE, pdFALSE, portTICK_PERIOD_MS);
|
||||
if ((bit & DATA_SEND_SUCCESS) != 0)
|
||||
{
|
||||
ESP_LOGI(TAG, "RF24 message sent success.");
|
||||
on_send->status = ZH_RF24_SEND_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGW(TAG, "RF24 message sent fail.");
|
||||
on_send->status = ZH_RF24_SEND_FAIL;
|
||||
}
|
||||
gpio_set_level(_init_config.ce_pin, 1);
|
||||
ESP_LOGI(TAG, "Outgoing RF24 data processing success.");
|
||||
if (esp_event_post(ZH_RF24, ZH_RF24_ON_SEND_EVENT, on_send, sizeof(zh_rf24_event_on_send_t), portTICK_PERIOD_MS) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "RF24 message processing task internal error.");
|
||||
}
|
||||
heap_caps_free(send_data->data);
|
||||
heap_caps_free(on_send);
|
||||
break;
|
||||
case ON_RECV:
|
||||
ESP_LOGI(TAG, "Incoming RF24 data processing begin.");
|
||||
zh_rf24_event_on_recv_t *recv_data = (zh_rf24_event_on_recv_t *)&queue.data;
|
||||
ESP_LOGI(TAG, "Incoming RF24 data processed success.");
|
||||
if (esp_event_post(ZH_RF24, ZH_RF24_ON_RECV_EVENT, recv_data, recv_data->data_len + 2, portTICK_PERIOD_MS) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "RF message processing task internal error.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void s_zh_rf24_irq_isr_handler(void *arg)
|
||||
static void _irq_isr_handler(void *arg)
|
||||
{
|
||||
xSemaphoreGiveFromISR(s_zh_rf24_irq_semaphore, NULL);
|
||||
xSemaphoreGiveFromISR(_irq_semaphore, NULL);
|
||||
}
|
||||
|
||||
static void s_zh_rf24_irq_processing(void *pvParameter)
|
||||
static void _irq_processing(void *pvParameter)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
xSemaphoreTake(s_zh_rf24_irq_semaphore, portMAX_DELAY);
|
||||
xSemaphoreTake(_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);
|
||||
@ -413,55 +471,55 @@ static void s_zh_rf24_irq_processing(void *pvParameter)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void s_zh_rf24_read_register(const uint8_t *reg, uint8_t *value, const uint8_t length)
|
||||
static void _read_register(const uint8_t *reg, uint8_t *value, const uint8_t length)
|
||||
{
|
||||
// uint8_t status = 0;
|
||||
gpio_set_level(s_zh_rf24_init_config.csn_pin, 0);
|
||||
gpio_set_level(_init_config.csn_pin, 0);
|
||||
spi_transaction_t spi_transaction = {0};
|
||||
spi_transaction.length = 8;
|
||||
spi_transaction.tx_buffer = ((*reg & 0x1F) | R_REGISTER);
|
||||
spi_transaction.rx_buffer = NULL;
|
||||
spi_device_transmit(s_zh_rf24_spi_handle, &spi_transaction);
|
||||
spi_device_transmit(_spi_handle, &spi_transaction);
|
||||
spi_transaction.length = length * 8;
|
||||
spi_transaction.tx_buffer = NULL;
|
||||
spi_transaction.rx_buffer = value;
|
||||
spi_device_transmit(s_zh_rf24_spi_handle, &spi_transaction);
|
||||
gpio_set_level(s_zh_rf24_init_config.csn_pin, 1);
|
||||
spi_device_transmit(_spi_handle, &spi_transaction);
|
||||
gpio_set_level(_init_config.csn_pin, 1);
|
||||
}
|
||||
|
||||
static void s_zh_rf24_write_register(const uint8_t *reg, uint8_t *value, const uint8_t length)
|
||||
static void _write_register(const uint8_t *reg, uint8_t *value, const uint8_t length)
|
||||
{
|
||||
// uint8_t status = 0;
|
||||
gpio_set_level(s_zh_rf24_init_config.csn_pin, 0);
|
||||
gpio_set_level(_init_config.csn_pin, 0);
|
||||
spi_transaction_t spi_transaction = {0};
|
||||
spi_transaction.length = 8;
|
||||
spi_transaction.tx_buffer = ((*reg & 0x1F) | W_REGISTER);
|
||||
spi_transaction.rx_buffer = NULL;
|
||||
spi_device_transmit(s_zh_rf24_spi_handle, &spi_transaction);
|
||||
spi_device_transmit(_spi_handle, &spi_transaction);
|
||||
spi_transaction.length = length * 8;
|
||||
spi_transaction.tx_buffer = value;
|
||||
spi_transaction.rx_buffer = NULL;
|
||||
spi_device_transmit(s_zh_rf24_spi_handle, &spi_transaction);
|
||||
gpio_set_level(s_zh_rf24_init_config.csn_pin, 1);
|
||||
spi_device_transmit(_spi_handle, &spi_transaction);
|
||||
gpio_set_level(_init_config.csn_pin, 1);
|
||||
}
|
||||
|
||||
static void s_zh_rf24_read_data(uint8_t *data, const uint8_t length)
|
||||
static void _read_data(uint8_t *data, const uint8_t length)
|
||||
{
|
||||
}
|
||||
|
||||
static void s_zh_rf24_write_data(uint8_t *data, const uint8_t length)
|
||||
static void _write_data(uint8_t *data, const uint8_t length)
|
||||
{
|
||||
}
|
||||
|
||||
static uint8_t s_zh_rf24_send_command(uint8_t *command)
|
||||
static uint8_t _send_command(uint8_t *command)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
gpio_set_level(s_zh_rf24_init_config.csn_pin, 0);
|
||||
gpio_set_level(_init_config.csn_pin, 0);
|
||||
spi_transaction_t spi_transaction = {0};
|
||||
spi_transaction.length = 8;
|
||||
spi_transaction.tx_buffer = command;
|
||||
spi_transaction.rx_buffer = status;
|
||||
spi_device_transmit(s_zh_rf24_spi_handle, &spi_transaction);
|
||||
gpio_set_level(s_zh_rf24_init_config.csn_pin, 1);
|
||||
spi_device_transmit(_spi_handle, &spi_transaction);
|
||||
gpio_set_level(_init_config.csn_pin, 1);
|
||||
return status;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user