Added event helpers and callbacks.
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
a628889e74
commit
67a2ff8c3b
|
@ -5,7 +5,7 @@ project(esp_nano_hosted)
|
||||||
set(NH_SOURCES
|
set(NH_SOURCES
|
||||||
"proto/esp_hosted_config.pb.c"
|
"proto/esp_hosted_config.pb.c"
|
||||||
"src/nh_ctrl_api.c"
|
"src/nh_ctrl_api.c"
|
||||||
"src/nh_event.c"
|
"src/nh_event_helpers.c"
|
||||||
"src/nh_shared_if.c"
|
"src/nh_shared_if.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,13 @@ typedef enum {
|
||||||
NH_EVENT_TYPE_INIT,
|
NH_EVENT_TYPE_INIT,
|
||||||
} nh_event_type_t;
|
} nh_event_type_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NH_EVENT_INIT_TAG_CAP = 0U,
|
||||||
|
NH_EVENT_INIT_TAG_FREQ = 1U,
|
||||||
|
NH_EVENT_INIT_TAG_CHIP_ID = 2U,
|
||||||
|
NH_EVENT_INIT_TAG_RAW_TP = 3U,
|
||||||
|
} nh_event_init_tag_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NH_EVENT_INIT_CAP_WLAN_SDIO = (1U << 0U),
|
NH_EVENT_INIT_CAP_WLAN_SDIO = (1U << 0U),
|
||||||
NH_EVENT_INIT_CAP_BT_UART = (1U << 1U),
|
NH_EVENT_INIT_CAP_BT_UART = (1U << 1U),
|
||||||
|
@ -33,4 +40,7 @@ typedef struct {
|
||||||
uint8_t spi_freq;
|
uint8_t spi_freq;
|
||||||
} nh_event_init_t;
|
} nh_event_init_t;
|
||||||
|
|
||||||
|
nh_ret_t nh_event_get_type(nh_event_type_t *type, uint8_t *event);
|
||||||
|
nh_ret_t nh_event_parse_init(nh_event_init_t *init, uint8_t *event);
|
||||||
|
|
||||||
#endif // NH_EVENT_H
|
#endif // NH_EVENT_H
|
|
@ -2,6 +2,7 @@
|
||||||
#define NH_SHARED_IF_H
|
#define NH_SHARED_IF_H
|
||||||
|
|
||||||
#include "nh_common.h"
|
#include "nh_common.h"
|
||||||
|
#include "nh_event_helpers.h"
|
||||||
|
|
||||||
/* OPS */
|
/* OPS */
|
||||||
typedef nh_ret_t (*nh_shared_if_ops_spi_xfer_t)(void *handle, uint8_t *tx_data, uint8_t *rx_data, uint32_t len);
|
typedef nh_ret_t (*nh_shared_if_ops_spi_xfer_t)(void *handle, uint8_t *tx_data, uint8_t *rx_data, uint32_t len);
|
||||||
|
@ -9,7 +10,7 @@ typedef nh_ret_t (*nh_shared_if_ops_reset_t)(void *handle);
|
||||||
typedef nh_ret_t (*nh_shared_if_ops_drdy_read_t)(void *handle, bool *rdy);
|
typedef nh_ret_t (*nh_shared_if_ops_drdy_read_t)(void *handle, bool *rdy);
|
||||||
|
|
||||||
/* Event callbacks */
|
/* Event callbacks */
|
||||||
typedef void (*nh_shared_if_cb_event_t)(void *handle, uint8_t *data);
|
typedef void (*nh_shared_if_cb_event_init_t)(void *handle, nh_event_init_t *init_event);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nh_shared_if_ops_spi_xfer_t xfer;
|
nh_shared_if_ops_spi_xfer_t xfer;
|
||||||
|
@ -18,7 +19,7 @@ typedef struct {
|
||||||
} nh_shared_if_ops_t;
|
} nh_shared_if_ops_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nh_shared_if_cb_event_t event;
|
nh_shared_if_cb_event_init_t init;
|
||||||
} nh_shared_if_cb_t;
|
} nh_shared_if_cb_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#include "nh_event.h"
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "nh_event_helpers.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Espressif wraps Tag-Length-Value(TLV) data in the packet for events
|
||||||
|
* | 1 | 1 | N |
|
||||||
|
* | Tag | Length | Value |
|
||||||
|
*/
|
||||||
|
|
||||||
|
nh_ret_t nh_event_get_type(nh_event_type_t *type, uint8_t *event) {
|
||||||
|
*type = event[0];
|
||||||
|
|
||||||
|
return NH_RET_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse Init event TLV data
|
||||||
|
* @param init
|
||||||
|
* @param data Event data
|
||||||
|
* @param max_len
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
nh_ret_t nh_event_parse_init(nh_event_init_t *init, uint8_t *event) {
|
||||||
|
uint8_t ptr = 0;
|
||||||
|
uint8_t data_len = event[1];
|
||||||
|
uint8_t *data = &event[2];
|
||||||
|
|
||||||
|
while (ptr < data_len) {
|
||||||
|
uint8_t tag = data[ptr];
|
||||||
|
uint8_t len = data[ptr + 1];
|
||||||
|
uint8_t *val = &data[ptr + 2];
|
||||||
|
|
||||||
|
switch (tag) {
|
||||||
|
case NH_EVENT_INIT_TAG_CAP:
|
||||||
|
/* Device capabilities, length should be 1 */
|
||||||
|
init->capabilities = val[0];
|
||||||
|
break;
|
||||||
|
case NH_EVENT_INIT_TAG_FREQ:
|
||||||
|
init->spi_freq = val[0];
|
||||||
|
break;
|
||||||
|
case NH_EVENT_INIT_TAG_CHIP_ID:
|
||||||
|
init->chip_id = val[0];
|
||||||
|
break;
|
||||||
|
case NH_EVENT_INIT_TAG_RAW_TP:
|
||||||
|
/* Not implemented */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += 2 + len; /* Increment, total length is 2 + payload length */
|
||||||
|
}
|
||||||
|
|
||||||
|
return NH_RET_SUCCESS;
|
||||||
|
}
|
|
@ -24,6 +24,10 @@ typedef enum {
|
||||||
NH_SHARED_IF_TYPE_PRIV = 4U,
|
NH_SHARED_IF_TYPE_PRIV = 4U,
|
||||||
} nh_xfer_type_t;
|
} nh_xfer_type_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NH_SHARED_IF_PRIV_TYPE_EVENT,
|
||||||
|
} nh_xfer_priv_type_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nh_xfer_type_t type;
|
nh_xfer_type_t type;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
|
@ -46,6 +50,9 @@ typedef struct __attribute__((packed)) {
|
||||||
}; /* Offset: 0x0B */
|
}; /* Offset: 0x0B */
|
||||||
} nh_xfer_pkt_hdr_t; /* Size: 0x0C (12 bytes) */
|
} nh_xfer_pkt_hdr_t; /* Size: 0x0C (12 bytes) */
|
||||||
|
|
||||||
|
static void nh_shared_if_dispatch_if_serial(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len);
|
||||||
|
static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload);
|
||||||
|
|
||||||
static uint16_t nh_shared_if_checksum_calculate(nh_xfer_pkt_hdr_t *hdr);
|
static uint16_t nh_shared_if_checksum_calculate(nh_xfer_pkt_hdr_t *hdr);
|
||||||
static bool nh_shared_if_checksum_verify(nh_xfer_pkt_hdr_t *hdr);
|
static bool nh_shared_if_checksum_verify(nh_xfer_pkt_hdr_t *hdr);
|
||||||
|
|
||||||
|
@ -212,38 +219,69 @@ void nh_shared_if_task(nh_shared_if_t *shared_if) {
|
||||||
|
|
||||||
item.type = LE16_TO_H(hdr->if_type);
|
item.type = LE16_TO_H(hdr->if_type);
|
||||||
item.buf_len = LE16_TO_H(hdr->len);
|
item.buf_len = LE16_TO_H(hdr->len);
|
||||||
|
item.buf = &shared_if->p_buf_frame_rx[LE16_TO_H(hdr->offset)]; /* DO NOT FREE THIS!! */
|
||||||
uint16_t payload_offset = LE16_TO_H(hdr->offset);
|
|
||||||
|
|
||||||
if (item.type == NH_SHARED_IF_TYPE_SERIAL) {
|
if (item.type == NH_SHARED_IF_TYPE_SERIAL) {
|
||||||
if (item.buf_len) {
|
if (!item.buf_len) {
|
||||||
/* Allocate payload */
|
return;
|
||||||
ret = shared_if->osa->buf_allocate(shared_if->osa->user_data, &item.buf, item.buf_len);
|
}
|
||||||
if (ret != NH_RET_SUCCESS) {
|
|
||||||
|
nh_shared_if_dispatch_if_serial(shared_if, item.buf, item.buf_len);
|
||||||
|
} else if (item.type == NH_SHARED_IF_TYPE_PRIV) {
|
||||||
|
if (!item.buf_len) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nh_shared_if_dispatch_if_priv(shared_if, hdr->priv_pkt_type, item.buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload) {
|
||||||
|
if (type == NH_SHARED_IF_PRIV_TYPE_EVENT) {
|
||||||
|
/* Event is using PRIV interface. */
|
||||||
|
nh_event_type_t evt_type;
|
||||||
|
nh_event_get_type(&evt_type, payload);
|
||||||
|
|
||||||
|
switch (evt_type) {
|
||||||
|
case NH_EVENT_TYPE_INIT: {
|
||||||
|
nh_event_init_t evt_init;
|
||||||
|
nh_event_parse_init(&evt_init, payload);
|
||||||
|
|
||||||
|
if (!shared_if->cb.init) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(item.buf, &shared_if->p_buf_frame_rx[payload_offset], item.buf_len);
|
shared_if->cb.init(shared_if->user_data, &evt_init);
|
||||||
}
|
|
||||||
|
|
||||||
/* Enqueue response */
|
|
||||||
ret = shared_if->osa->queue_enqueue(shared_if->osa->user_data, shared_if->p_queue_rx_ctrl, &item, 0);
|
|
||||||
if (ret != NH_RET_SUCCESS) {
|
|
||||||
/* Queue is full, maybe the ctrl interface is not active. */
|
|
||||||
shared_if->osa->buf_free(shared_if->osa->user_data, item.buf);
|
|
||||||
}
|
|
||||||
} else if (item.type == NH_SHARED_IF_TYPE_PRIV) {
|
|
||||||
/* Event is using PRIV interface. */
|
|
||||||
if (item.buf_len) {
|
|
||||||
if (shared_if->cb.event) {
|
|
||||||
/* Note: This is a blocking callback !! */
|
|
||||||
shared_if->cb.event(shared_if->user_data, &shared_if->p_buf_frame_rx[payload_offset]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nh_shared_if_dispatch_if_serial(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len) {
|
||||||
|
nh_ret_t ret = NH_RET_SUCCESS;
|
||||||
|
|
||||||
|
nh_xfer_queue_item_t item;
|
||||||
|
|
||||||
|
item.type = NH_SHARED_IF_TYPE_SERIAL;
|
||||||
|
item.buf_len = len;
|
||||||
|
|
||||||
|
/* Allocate payload */
|
||||||
|
ret = shared_if->osa->buf_allocate(shared_if->osa->user_data, &item.buf, item.buf_len);
|
||||||
|
if (ret != NH_RET_SUCCESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(item.buf, payload, item.buf_len);
|
||||||
|
|
||||||
|
/* Enqueue response */
|
||||||
|
ret = shared_if->osa->queue_enqueue(shared_if->osa->user_data, shared_if->p_queue_rx_ctrl, &item, 0);
|
||||||
|
if (ret != NH_RET_SUCCESS) {
|
||||||
|
/* Queue is full, maybe the ctrl interface is not active, drop the packet */
|
||||||
|
shared_if->osa->buf_free(shared_if->osa->user_data, item.buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint16_t nh_shared_if_checksum_calculate(nh_xfer_pkt_hdr_t *hdr) {
|
static uint16_t nh_shared_if_checksum_calculate(nh_xfer_pkt_hdr_t *hdr) {
|
||||||
uint16_t checksum = 0U;
|
uint16_t checksum = 0U;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue