169 lines
4.7 KiB
C
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
|
|
|