Files
2025-12-03 11:12:34 +08:00

169 lines
4.7 KiB
C

#include "board_config.h"
#include "includes.h"
#include "app_config.h"
#include "chargebox.h"
#include "clock.h"
#include "uart.h"
#include "asm/gpio_hw.h"
#if (TCFG_CHARGE_BOX_ENABLE)
#define BUF_LEN (64)
struct chargebox_handle {
const struct chargebox_platform_data *data;
s32 udev;
volatile u8 lr_flag;
volatile u8 rx_index;
};
static u8 chg_uart_buf[BUF_LEN] __attribute__((aligned(4)));
static u8 chg_uart_dma_buf[BUF_LEN] __attribute__((aligned(4)));
#define __this (&hdl)
static struct chargebox_handle hdl;
extern void chargebox_data_deal(u8 cmd, u8 l_r, u8 *data, u8 length);
void __attribute__((weak)) chargebox_data_deal(u8 cmd, u8 l_r, u8 *data, u8 len)
{
}
static void chargebox_uart_isr_cb(uart_dev uart_num, enum uart_event event)
{
if (event == UART_EVENT_TX_DONE) {
chargebox_data_deal(CMD_COMPLETE, __this->lr_flag, NULL, 0);
} else if (event == UART_EVENT_RX_DATA) {
uart_recv_bytes(__this->udev, &chg_uart_buf[__this->rx_index], 1);
chargebox_data_deal(CMD_RECVBYTE, __this->lr_flag, NULL, 0);
if (chg_uart_buf[0] == 0x55) {
__this->rx_index++;
} else {
return;
}
//耳机发来数据长度为head 2byte + (data len +1) + 校验码 1byte
if ((__this->rx_index > 3) && (__this->rx_index == (chg_uart_buf[2] + 4))) {
chargebox_data_deal(CMD_RECVDATA, __this->lr_flag, chg_uart_buf, __this->rx_index);
__this->rx_index = 0;
}
}
}
u8 chargebox_write(u8 l_r, u8 *data, u8 len)
{
if ((len == 0) || (len > BUF_LEN) || (__this->udev < 0)) {
return 0;
}
__this->lr_flag = l_r;
if (((u32)data) % 4) {//4byte对齐
ASSERT(0, "%s: unaligned accesses!", __func__);
}
memcpy(chg_uart_buf, data, len);
uart_send_bytes(__this->udev, chg_uart_buf, (u32)len);
return len;
}
void chargebox_open(u8 l_r, u8 mode)
{
u32 uart_timeout;
u32 io_port;
s32 ret;
struct uart_config config = {0};
struct uart_dma_config dma = {0};
if (mode == MODE_RECVDATA) {
__this->rx_index = 0;
}
if (__this->udev >= 0) {
return;
}
if (l_r == EAR_L) {
io_port = __this->data->L_port;
} else {
io_port = __this->data->R_port;
}
__this->lr_flag = l_r;
config.baud_rate = __this->data->baudrate;
config.tx_pin = io_port;
config.rx_pin = io_port;
config.parity = UART_PARITY_DISABLE;
config.tx_wait_mutex = 0;
__this->udev = uart_init(-1, &config);
if (__this->udev < 0) {
goto __err_exit;
}
//确保2byte的时间
uart_timeout = 25 * 1000000 / __this->data->baudrate;//us
dma.rx_timeout_thresh = uart_timeout;
dma.frame_size = 1;
dma.event_mask = UART_EVENT_RX_DATA | UART_EVENT_RX_TIMEOUT | UART_EVENT_TX_DONE;
dma.irq_priority = 2;
dma.irq_callback = chargebox_uart_isr_cb;
dma.rx_cbuffer = chg_uart_dma_buf;
dma.rx_cbuffer_size = BUF_LEN;
ret = uart_dma_init(__this->udev, &dma);
if (ret < 0) {
goto __err_exit;
}
return;
__err_exit:
ASSERT(0, "chargebox open err!\n");
if (__this->udev >= 0) {
uart_deinit(__this->udev);
}
__this->udev = -1;
}
void chargebox_close(u8 l_r)
{
if (__this->udev < 0) {
return;
}
uart_deinit(__this->udev);
__this->udev = -1;
if (l_r == EAR_L) {
gpio_hw_set_pull_up(IO_PORT_SPILT(__this->data->L_port), GPIO_PULLUP_DISABLE);
gpio_hw_set_pull_down(IO_PORT_SPILT(__this->data->L_port), GPIO_PULLDOWN_DISABLE);
gpio_hw_set_die(IO_PORT_SPILT(__this->data->L_port), 1);
gpio_hw_set_dieh(IO_PORT_SPILT(__this->data->L_port), 1);
gpio_set_mode(IO_PORT_SPILT(__this->data->L_port), PORT_OUTPUT_HIGH);
} else {
gpio_hw_set_pull_up(IO_PORT_SPILT(__this->data->R_port), GPIO_PULLUP_DISABLE);
gpio_hw_set_pull_down(IO_PORT_SPILT(__this->data->R_port), GPIO_PULLDOWN_DISABLE);
gpio_hw_set_die(IO_PORT_SPILT(__this->data->R_port), 1);
gpio_hw_set_dieh(IO_PORT_SPILT(__this->data->R_port), 1);
gpio_set_mode(IO_PORT_SPILT(__this->data->R_port), PORT_OUTPUT_HIGH);
}
}
void chargebox_set_baud(u32 baudrate)
{
u32 uart_timeout;
if (__this->udev < 0) {
return;
}
//确保2byte的时间
uart_timeout = 25 * 1000000 / baudrate;
uart_set_baudrate(__this->udev, baudrate);
uart_set_rx_timeout_thresh(__this->udev, uart_timeout);
//重新初始化DMA,防止高波特率时候出现分包行为
uart_dma_rx_reset(__this->udev);
}
void chargebox_init(const struct chargebox_platform_data *data)
{
__this->data = (struct chargebox_platform_data *)data;
ASSERT(data);
__this->udev = -1;
}
#endif