pinebuds/platform/hal/hal_cmd.c

512 lines
12 KiB
C
Raw Permalink Normal View History

2022-08-15 04:20:27 -05:00
/***************************************************************************
*
* Copyright 2015-2019 BES.
* All rights reserved. All unpublished rights reserved.
*
* No part of this work may be used or reproduced in any form or by any
* means, or stored in a database or retrieval system, without prior written
* permission of BES.
*
* Use of this work is governed by a license granted by BES.
* This work contains confidential and proprietary information of
* BES. which is protected by copyright, trade secret,
* trademark and other intellectual property rights.
*
****************************************************************************/
#include "hal_cmd.h"
#include "hal_iomux.h"
#include "hal_timer.h"
2022-08-15 04:20:27 -05:00
#include "hal_trace.h"
#include "hal_uart.h"
2022-08-15 04:20:27 -05:00
#include "string.h"
/*
|-----|-------|----------------------------------|
| | crc | Discription |
| | ----- | -------------------------------- |
| | -3 | Can not find head name |
| | ----- | -------------------------------- |
| | -2 | Can not find callback function |
| | ----- | -------------------------------- |
| res | -1 | Unknown issue |
| | ----- | -------------------------------- |
| | 0 | OK |
| | ----- | -------------------------------- |
| | 1 | Data length is mismatching |
| | ----- | -------------------------------- |
| | >1 | Issue from application |
|-----|-------|----------------------------------|
*/
#define HAL_CMD_PREFIX_SIZE 4
#define HAL_CMD_CRC_SIZE 4
#define HAL_CMD_NAME_SIZE 12
#define HAL_CMD_LEN_SIZE 4
#define HAL_CMD_DATA_MAX_SIZE 1024 * 3
2022-08-15 04:20:27 -05:00
// #define HAL_CMD_PREFIX_OFFSET 0
// #define HAL_CMD_TYPE_OFFSET 1
// #define HAL_CMD_SEQ_OFFSET 2
// #define HAL_CMD_LEN_OFFSET 3
// #define HAL_CMD_CMD_OFFSET 4
// #define HAL_CMD_DATA_OFFSET 5
// #define HAL_CMD_PREFIX 0xFE
// #define HAL_CMD_TYPE 0xA0
#define HAL_CMD_RX_BUF_SIZE \
(HAL_CMD_PREFIX_SIZE + HAL_CMD_NAME_SIZE + HAL_CMD_CRC_SIZE + \
HAL_CMD_LEN_SIZE + HAL_CMD_DATA_MAX_SIZE)
#define HAL_CMD_TX_BUF_SIZE (100)
2022-08-15 04:20:27 -05:00
#define HAL_CMD_LIST_NUM 10
2022-08-15 04:20:27 -05:00
#ifdef USB_EQ_TUNING
#define STATIC
#else
#define STATIC static
#endif
#ifdef USB_EQ_TUNING
#ifdef __PC_CMD_UART__
#error "USB_EQ_TUNING can not be defined together with PC_CMD_UART"
#endif
#endif
typedef struct {
uint32_t len;
uint8_t data[HAL_CMD_TX_BUF_SIZE - 13];
} hal_cmd_res_payload_t;
typedef struct {
int prefix;
int crc;
char name[HAL_CMD_NAME_SIZE];
} hal_cmd_res_t;
2022-08-15 04:20:27 -05:00
typedef struct {
int prefix;
int crc;
char *name;
uint32_t len;
uint8_t *data;
} hal_cmd_cfg_t;
typedef struct {
char name[HAL_CMD_NAME_SIZE];
hal_cmd_callback_t callback;
} hal_cmd_list_t;
typedef struct {
uint8_t uart_work;
hal_cmd_rx_status_t rx_status;
uint8_t cur_seq;
2022-08-15 04:20:27 -05:00
#ifdef __PC_CMD_UART__
uint8_t rx_len;
2022-08-15 04:20:27 -05:00
#endif
uint8_t tx_len;
2022-08-15 04:20:27 -05:00
#ifdef __PC_CMD_UART__
uint8_t rx_buf[HAL_CMD_RX_BUF_SIZE];
2022-08-15 04:20:27 -05:00
#endif
uint8_t tx_buf[HAL_CMD_TX_BUF_SIZE];
2022-08-15 04:20:27 -05:00
hal_cmd_res_t res;
hal_cmd_res_payload_t res_payload;
2022-08-15 04:20:27 -05:00
uint32_t list_num;
hal_cmd_list_t list[HAL_CMD_LIST_NUM];
2022-08-15 04:20:27 -05:00
} hal_cmd_t;
hal_cmd_t hal_cmd;
CMD_CALLBACK_HANDLER_T hal_cmd_callback = NULL;
#ifdef __PC_CMD_UART__
#define HAL_CMD_ID HAL_UART_ID_0
2022-08-15 04:20:27 -05:00
static const struct HAL_UART_CFG_T hal_cmd_cfg = {
.parity = HAL_UART_PARITY_NONE,
.stop = HAL_UART_STOP_BITS_1,
.data = HAL_UART_DATA_BITS_8,
.flow = HAL_UART_FLOW_CONTROL_NONE, // HAL_UART_FLOW_CONTROL_RTSCTS,
2022-08-15 04:20:27 -05:00
.tx_level = HAL_UART_FIFO_LEVEL_1_2,
.rx_level = HAL_UART_FIFO_LEVEL_1_2,
.baud = 115200,
.dma_rx = true,
.dma_tx = true,
.dma_rx_stop_on_err = false,
};
#endif
#define HAL_CMD_TRACE TRACE
2022-08-15 04:20:27 -05:00
#ifdef __PC_CMD_UART__
STATIC int hal_cmd_list_process(uint8_t *buf);
#endif
static int hal_cmd_list_register(char *name, hal_cmd_callback_t callback);
#ifdef __PC_CMD_UART__
void hal_cmd_break_irq_handler(void) {
HAL_CMD_TRACE(1, "%s", __func__);
2022-08-15 04:20:27 -05:00
// gElCtx.sync_step = EL_SYNC_ERROR;
2022-08-15 04:20:27 -05:00
}
void hal_cmd_dma_rx_irq_handler(uint32_t xfer_size, int dma_error,
union HAL_UART_IRQ_T status) {
// uint8_t prefix = gpElUartCtx->rx_buf[EL_PREFIX_OFFSET];
// uint8_t type = gpElUartCtx->rx_buf[EL_TYPE_OFFSET];
// uint8_t len = gpElUartCtx->rx_buf[EL_LEN_OFFSET];
// uint8_t cmd = gpElUartCtx->rx_buf[EL_CMD_OFFSET];
HAL_CMD_TRACE(5,
"%s: xfer_size[%d], dma_error[%x], status[%x], rx_status[%d]",
__func__, xfer_size, dma_error, status.reg, hal_cmd.rx_status);
if (status.BE) {
hal_cmd_break_irq_handler();
return;
}
if (hal_cmd.rx_status != HAL_CMD_RX_START) {
return;
}
if (dma_error || status.FE || status.OE || status.PE || status.BE) {
// TODO:
;
} else {
// mask.RT = 1
hal_cmd.rx_len = xfer_size;
hal_cmd.rx_status = HAL_CMD_RX_DONE;
hal_cmd_callback(hal_cmd.rx_status);
}
2022-08-15 04:20:27 -05:00
}
#endif
int hal_cmd_init(void) {
2022-08-15 04:20:27 -05:00
#ifdef __PC_CMD_UART__
HAL_CMD_TRACE(1, "[%s]", __func__);
if (HAL_CMD_ID == HAL_UART_ID_0) {
hal_iomux_set_uart0();
} else if (HAL_CMD_ID == HAL_UART_ID_1) {
hal_iomux_set_uart1();
}
2022-08-15 04:20:27 -05:00
#endif
#ifdef USB_AUDIO_APP
hal_cmd_set_callback(hal_cmd_run);
2022-08-15 04:20:27 -05:00
#endif
return 0;
2022-08-15 04:20:27 -05:00
}
void hal_cmd_set_callback(CMD_CALLBACK_HANDLER_T handler) {
hal_cmd_callback = handler;
2022-08-15 04:20:27 -05:00
}
#ifdef __PC_CMD_UART__
static union HAL_UART_IRQ_T mask;
#endif
int hal_cmd_open(void) {
2022-08-15 04:20:27 -05:00
#ifdef __PC_CMD_UART__
int ret = -1;
2022-08-15 04:20:27 -05:00
ret = hal_uart_open(HAL_CMD_ID, &hal_cmd_cfg);
ASSERT(!ret, "!!%s: UART open failed (%d)!!", __func__, ret);
2022-08-15 04:20:27 -05:00
hal_uart_irq_set_dma_handler(HAL_CMD_ID, hal_cmd_dma_rx_irq_handler, NULL);
2022-08-15 04:20:27 -05:00
// Do not enable tx and rx interrupt, use dma
mask.reg = 0;
mask.BE = 1;
mask.FE = 1;
mask.OE = 1;
mask.PE = 1;
mask.RT = 1;
hal_uart_irq_set_mask(HAL_CMD_ID, mask);
2022-08-15 04:20:27 -05:00
hal_cmd.uart_work = 1;
hal_cmd.rx_status = HAL_CMD_RX_STOP;
hal_cmd_callback(hal_cmd.rx_status);
2022-08-15 04:20:27 -05:00
#endif
return 0;
2022-08-15 04:20:27 -05:00
}
int hal_cmd_close(void) {
2022-08-15 04:20:27 -05:00
#ifdef __PC_CMD_UART__
mask.reg = 0;
hal_uart_irq_set_mask(HAL_CMD_ID, mask);
hal_uart_irq_set_dma_handler(HAL_CMD_ID, NULL, NULL);
hal_uart_close(HAL_CMD_ID);
2022-08-15 04:20:27 -05:00
hal_cmd.uart_work = 0;
2022-08-15 04:20:27 -05:00
#endif
return 0;
2022-08-15 04:20:27 -05:00
}
int hal_cmd_register(char *name, hal_cmd_callback_t callback) {
int ret = -1;
2022-08-15 04:20:27 -05:00
ASSERT(strlen(name) < HAL_CMD_NAME_SIZE,
"[%s] strlen(%s) = %d >= HAL_CMD_NAME_SIZE", __func__, name,
strlen(name));
2022-08-15 04:20:27 -05:00
ret = hal_cmd_list_register(name, callback);
2022-08-15 04:20:27 -05:00
return ret;
2022-08-15 04:20:27 -05:00
}
#ifdef __PC_CMD_UART__
static int hal_cmd_send(void) {
int ret = -1;
2022-08-15 04:20:27 -05:00
if (!hal_cmd.uart_work) {
hal_cmd_open();
}
2022-08-15 04:20:27 -05:00
ret =
hal_uart_dma_send(HAL_CMD_ID, hal_cmd.tx_buf, hal_cmd.tx_len, NULL, NULL);
2022-08-15 04:20:27 -05:00
HAL_CMD_TRACE(4, "%s: %d - %d - %d", __func__, hal_cmd.tx_len,
hal_cmd.uart_work, ret);
2022-08-15 04:20:27 -05:00
return ret;
2022-08-15 04:20:27 -05:00
}
static int hal_cmd_rx_start(void) {
int ret = -1;
2022-08-15 04:20:27 -05:00
if (!hal_cmd.uart_work) {
hal_cmd_open();
}
2022-08-15 04:20:27 -05:00
ret = hal_uart_dma_recv_mask(HAL_CMD_ID, hal_cmd.rx_buf, HAL_CMD_RX_BUF_SIZE,
NULL, NULL, &mask); // HAL_CMD_RX_BUF_SIZE
2022-08-15 04:20:27 -05:00
ASSERT(!ret, "!!%s: UART recv failed (%d)!!", __func__, ret);
2022-08-15 04:20:27 -05:00
hal_cmd.rx_status = HAL_CMD_RX_START;
hal_cmd_callback(hal_cmd.rx_status);
return ret;
2022-08-15 04:20:27 -05:00
}
static int hal_cmd_rx_process(void) {
int ret = -1;
2022-08-15 04:20:27 -05:00
HAL_CMD_TRACE(1, "[%s] start...", __func__);
2022-08-15 04:20:27 -05:00
ret = hal_cmd_list_process(hal_cmd.rx_buf);
2022-08-15 04:20:27 -05:00
hal_cmd.rx_status = HAL_CMD_RX_STOP;
hal_cmd_callback(hal_cmd.rx_status);
return ret;
2022-08-15 04:20:27 -05:00
}
#endif
void hal_cmd_set_res_playload(uint8_t *data, int len) {
hal_cmd.res_payload.len = len;
memcpy(hal_cmd.res_payload.data, data, len);
2022-08-15 04:20:27 -05:00
}
#ifdef __PC_CMD_UART__
static int hal_cmd_tx_process(void) {
int ret = -1;
2022-08-15 04:20:27 -05:00
HAL_CMD_TRACE(1, "[%s] start...", __func__);
2022-08-15 04:20:27 -05:00
#if 0
// Test loop
hal_cmd.tx_len = hal_cmd.rx_len;
memcpy(hal_cmd.tx_buf, hal_cmd.rx_buf, hal_cmd.rx_len);
#endif
#if 1
hal_cmd.tx_len = sizeof(hal_cmd.res);
TRACE(5, "[%s] len : %d, %c, %d, %s", __func__, hal_cmd.tx_len,
hal_cmd.res.prefix, hal_cmd.res.crc, hal_cmd.res.name);
memcpy(hal_cmd.tx_buf, &hal_cmd.res, hal_cmd.tx_len);
if (hal_cmd.res_payload.len) {
memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, &hal_cmd.res_payload.len,
sizeof(hal_cmd.res_payload.len));
hal_cmd.tx_len += sizeof(hal_cmd.res_payload.len);
memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, hal_cmd.res_payload.data,
hal_cmd.res_payload.len);
hal_cmd.tx_len += hal_cmd.res_payload.len;
memset(&hal_cmd.res_payload, 0, sizeof(hal_cmd.res_payload));
}
2022-08-15 04:20:27 -05:00
#else
char send_string[] = "791,";
hal_cmd.tx_len = sizeof(send_string);
memcpy(hal_cmd.tx_buf, send_string, hal_cmd.tx_len);
2022-08-15 04:20:27 -05:00
#endif
hal_cmd_send();
2022-08-15 04:20:27 -05:00
return ret;
2022-08-15 04:20:27 -05:00
}
#endif
#ifdef USB_EQ_TUNING
void hal_cmd_tx_process(uint8_t **ppbuf, uint16_t *plen) {
hal_cmd.tx_len = sizeof(hal_cmd.res);
2022-08-15 04:20:27 -05:00
memcpy(hal_cmd.tx_buf, &hal_cmd.res, hal_cmd.tx_len);
2022-08-15 04:20:27 -05:00
if (hal_cmd.res_payload.len) {
memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, &hal_cmd.res_payload.len,
sizeof(hal_cmd.res_payload.len));
hal_cmd.tx_len += sizeof(hal_cmd.res_payload.len);
2022-08-15 04:20:27 -05:00
memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, hal_cmd.res_payload.data,
hal_cmd.res_payload.len);
hal_cmd.tx_len += hal_cmd.res_payload.len;
2022-08-15 04:20:27 -05:00
memset(&hal_cmd.res_payload, 0, sizeof(hal_cmd.res_payload));
}
2022-08-15 04:20:27 -05:00
*ppbuf = hal_cmd.tx_buf;
*plen = hal_cmd.tx_len;
2022-08-15 04:20:27 -05:00
}
#endif
#ifdef __PC_CMD_UART__
#ifdef USB_AUDIO_APP
void hal_cmd_run(hal_cmd_rx_status_t status)
2022-08-15 04:20:27 -05:00
#else
int hal_cmd_run(hal_cmd_rx_status_t status)
2022-08-15 04:20:27 -05:00
#endif
{
int ret = -1;
2022-08-15 04:20:27 -05:00
// static uint32_t pre_time_ms = 0, curr_ticks = 0, curr_time_ms = 0;
2022-08-15 04:20:27 -05:00
// curr_ticks = hal_sys_timer_get();
// curr_time_ms = TICKS_TO_MS(curr_ticks);
2022-08-15 04:20:27 -05:00
// if(curr_time_ms - pre_time_ms > 1000)
// {
// HAL_CMD_TRACE(1,"[%s] start...", __func__);
// pre_time_ms = curr_time_ms;
// }
2022-08-15 04:20:27 -05:00
if (status == HAL_CMD_RX_DONE) {
ret = hal_cmd_rx_process();
2022-08-15 04:20:27 -05:00
if (ret) {
hal_cmd.res.crc = ret;
2022-08-15 04:20:27 -05:00
}
ret = hal_cmd_tx_process();
}
if (status == HAL_CMD_RX_STOP) {
ret = hal_cmd_rx_start();
}
2022-08-15 04:20:27 -05:00
#ifndef USB_AUDIO_APP
return ret;
2022-08-15 04:20:27 -05:00
#endif
}
#endif
// List process
static int hal_cmd_list_get_id(char *name) {
for (int i = 0; i < hal_cmd.list_num; i++) {
if (!strcmp(hal_cmd.list[i].name, name)) {
return i;
2022-08-15 04:20:27 -05:00
}
}
2022-08-15 04:20:27 -05:00
TRACE(2, "[%s] rx = %s", __func__, name);
for (int i = 0; i < hal_cmd.list_num; i++) {
TRACE(3, "[%s] list[%d] = %s", __func__, i, hal_cmd.list[i].name);
}
return -1;
2022-08-15 04:20:27 -05:00
}
static int hal_cmd_list_add(char *name, hal_cmd_callback_t callback) {
if (hal_cmd.list_num < HAL_CMD_LIST_NUM) {
memcpy(hal_cmd.list[hal_cmd.list_num].name, name, strlen(name));
hal_cmd.list[hal_cmd.list_num].callback = callback;
hal_cmd.list_num++;
2022-08-15 04:20:27 -05:00
return 0;
} else {
return -1;
}
2022-08-15 04:20:27 -05:00
}
static int hal_cmd_list_register(char *name, hal_cmd_callback_t callback) {
int ret = -1;
2022-08-15 04:20:27 -05:00
if (hal_cmd_list_get_id(name) == -1) {
ret = hal_cmd_list_add(name, callback);
} else {
ret = -1;
}
2022-08-15 04:20:27 -05:00
return ret;
2022-08-15 04:20:27 -05:00
}
#if defined(USB_EQ_TUNING) || defined(__PC_CMD_UART__)
static int hal_cmd_list_parse(uint8_t *buf, hal_cmd_cfg_t *cfg) {
cfg->prefix = *((uint32_t *)buf);
HAL_CMD_TRACE(2, "[%s] PREFIX = %c", __func__, cfg->prefix);
buf += HAL_CMD_PREFIX_SIZE;
hal_cmd.res.prefix = cfg->prefix;
2022-08-15 04:20:27 -05:00
cfg->crc = *((uint32_t *)buf);
HAL_CMD_TRACE(2, "[%s] crc = %d", __func__, cfg->crc);
buf += HAL_CMD_CRC_SIZE;
hal_cmd.res.crc = cfg->crc;
2022-08-15 04:20:27 -05:00
cfg->name = (char *)buf;
HAL_CMD_TRACE(2, "[%s] NAME = %s", __func__, cfg->name);
buf += HAL_CMD_NAME_SIZE;
memcpy(hal_cmd.res.name, cfg->name, HAL_CMD_NAME_SIZE);
2022-08-15 04:20:27 -05:00
cfg->len = *((uint32_t *)buf);
HAL_CMD_TRACE(2, "[%s] LEN = %d", __func__, cfg->len);
buf += HAL_CMD_LEN_SIZE;
2022-08-15 04:20:27 -05:00
cfg->data = buf;
2022-08-15 04:20:27 -05:00
return 0;
2022-08-15 04:20:27 -05:00
}
STATIC int hal_cmd_list_process(uint8_t *buf) {
int ret = -1;
int id = 0;
hal_cmd_cfg_t cfg;
2022-08-15 04:20:27 -05:00
hal_cmd_list_parse(buf, &cfg);
2022-08-15 04:20:27 -05:00
id = hal_cmd_list_get_id(cfg.name);
2022-08-15 04:20:27 -05:00
if (id == -1) {
TRACE(2, "[%s] %s is invalid", __func__, cfg.name);
return -2;
}
2022-08-15 04:20:27 -05:00
if (hal_cmd.list[id].callback) {
ret = hal_cmd.list[id].callback(cfg.data, cfg.len);
} else {
TRACE(2, "[%s] %s has not callback", __func__, hal_cmd.list[id].name);
ret = -3;
}
2022-08-15 04:20:27 -05:00
return ret;
2022-08-15 04:20:27 -05:00
}
#endif