/*************************************************************************** * * 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_iomux.h" #include "hal_cmd.h" #include "hal_uart.h" #include "hal_trace.h" #include "string.h" #include "hal_timer.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 // #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) #define HAL_CMD_LIST_NUM 10 #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; 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; #ifdef __PC_CMD_UART__ uint8_t rx_len; #endif uint8_t tx_len; #ifdef __PC_CMD_UART__ uint8_t rx_buf[HAL_CMD_RX_BUF_SIZE]; #endif uint8_t tx_buf[HAL_CMD_TX_BUF_SIZE]; hal_cmd_res_t res; hal_cmd_res_payload_t res_payload; uint32_t list_num; hal_cmd_list_t list[HAL_CMD_LIST_NUM]; } 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 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, .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 #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__); // gElCtx.sync_step = EL_SYNC_ERROR; } 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); } } #endif int hal_cmd_init (void) { #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(); } #endif #ifdef USB_AUDIO_APP hal_cmd_set_callback(hal_cmd_run); #endif return 0; } void hal_cmd_set_callback(CMD_CALLBACK_HANDLER_T handler) { hal_cmd_callback = handler; } #ifdef __PC_CMD_UART__ static union HAL_UART_IRQ_T mask; #endif int hal_cmd_open (void) { #ifdef __PC_CMD_UART__ int ret = -1; ret = hal_uart_open(HAL_CMD_ID, &hal_cmd_cfg); ASSERT(!ret, "!!%s: UART open failed (%d)!!", __func__, ret); hal_uart_irq_set_dma_handler(HAL_CMD_ID, hal_cmd_dma_rx_irq_handler, NULL); // 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); hal_cmd.uart_work = 1; hal_cmd.rx_status = HAL_CMD_RX_STOP; hal_cmd_callback(hal_cmd.rx_status); #endif return 0; } int hal_cmd_close (void) { #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); hal_cmd.uart_work = 0; #endif return 0; } int hal_cmd_register(char *name, hal_cmd_callback_t callback) { int ret = -1; ASSERT(strlen(name) < HAL_CMD_NAME_SIZE, "[%s] strlen(%s) = %d >= HAL_CMD_NAME_SIZE", __func__, name, strlen(name)); ret = hal_cmd_list_register(name, callback); return ret; } #ifdef __PC_CMD_UART__ static int hal_cmd_send (void) { int ret = -1; if (!hal_cmd.uart_work) { hal_cmd_open(); } ret = hal_uart_dma_send(HAL_CMD_ID, hal_cmd.tx_buf, hal_cmd.tx_len, NULL, NULL); HAL_CMD_TRACE(4,"%s: %d - %d - %d", __func__, hal_cmd.tx_len, hal_cmd.uart_work, ret); return ret; } static int hal_cmd_rx_start (void) { int ret = -1; if (!hal_cmd.uart_work) { hal_cmd_open(); } 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 ASSERT(!ret, "!!%s: UART recv failed (%d)!!", __func__, ret); hal_cmd.rx_status = HAL_CMD_RX_START; hal_cmd_callback(hal_cmd.rx_status); return ret; } static int hal_cmd_rx_process (void) { int ret = -1; HAL_CMD_TRACE(1,"[%s] start...", __func__); ret = hal_cmd_list_process(hal_cmd.rx_buf); hal_cmd.rx_status = HAL_CMD_RX_STOP; hal_cmd_callback(hal_cmd.rx_status); return ret; } #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); } #ifdef __PC_CMD_UART__ static int hal_cmd_tx_process (void) { int ret = -1; HAL_CMD_TRACE(1,"[%s] start...", __func__); #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)); } #else char send_string[] = "791,"; hal_cmd.tx_len = sizeof(send_string); memcpy(hal_cmd.tx_buf, send_string, hal_cmd.tx_len); #endif hal_cmd_send(); return ret; } #endif #ifdef USB_EQ_TUNING void hal_cmd_tx_process (uint8_t** ppbuf, uint16_t* plen) { hal_cmd.tx_len = sizeof(hal_cmd.res); 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)); } *ppbuf = hal_cmd.tx_buf; *plen = hal_cmd.tx_len; } #endif #ifdef __PC_CMD_UART__ #ifdef USB_AUDIO_APP void hal_cmd_run (hal_cmd_rx_status_t status) #else int hal_cmd_run (hal_cmd_rx_status_t status) #endif { int ret = -1; // static uint32_t pre_time_ms = 0, curr_ticks = 0, curr_time_ms = 0; // curr_ticks = hal_sys_timer_get(); // curr_time_ms = TICKS_TO_MS(curr_ticks); // if(curr_time_ms - pre_time_ms > 1000) // { // HAL_CMD_TRACE(1,"[%s] start...", __func__); // pre_time_ms = curr_time_ms; // } if(status == HAL_CMD_RX_DONE) { ret = hal_cmd_rx_process(); if (ret) { hal_cmd.res.crc = ret; } ret = hal_cmd_tx_process(); } if(status == HAL_CMD_RX_STOP) { ret = hal_cmd_rx_start(); } #ifndef USB_AUDIO_APP return ret; #endif } #endif // List process static int hal_cmd_list_get_id(char *name) { for(int i=0;iprefix = *((uint32_t *)buf); HAL_CMD_TRACE(2,"[%s] PREFIX = %c", __func__, cfg->prefix); buf += HAL_CMD_PREFIX_SIZE; hal_cmd.res.prefix = cfg->prefix; 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; 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); cfg->len = *((uint32_t *)buf); HAL_CMD_TRACE(2,"[%s] LEN = %d", __func__, cfg->len); buf += HAL_CMD_LEN_SIZE; cfg->data = buf; return 0; } STATIC int hal_cmd_list_process(uint8_t *buf) { int ret = -1; int id = 0; hal_cmd_cfg_t cfg; hal_cmd_list_parse(buf, &cfg); id = hal_cmd_list_get_id(cfg.name); if(id == -1) { TRACE(2,"[%s] %s is invalid", __func__, cfg.name); return -2; } 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; } return ret; } #endif