205 lines
5.1 KiB
C
205 lines
5.1 KiB
C
#include "generic/typedef.h"
|
|
#include "gpio.h"
|
|
#include "asm/power_interface.h"
|
|
#include "asm/hwi.h"
|
|
#include "asm/gpio_hw.h"
|
|
#include "asm/charge.h"
|
|
#include "asm/chargestore.h"
|
|
#include "update.h"
|
|
#include "app_config.h"
|
|
#include "clock.h"
|
|
#include "uart.h"
|
|
|
|
#include "asm/power/p33/charge_hw.h"
|
|
|
|
#if (TCFG_CHARGESTORE_ENABLE || TCFG_TEST_BOX_ENABLE || TCFG_ANC_BOX_ENABLE)
|
|
struct chargestore_handle {
|
|
const struct chargestore_platform_data *data;
|
|
s32 udev;
|
|
};
|
|
|
|
#define DMA_BUF_LEN 544
|
|
#define __this (&hdl)
|
|
static struct chargestore_handle hdl;
|
|
u8 uart_rx_buf[DMA_BUF_LEN] __attribute__((aligned(4)));
|
|
u8 uart_dma_buf[DMA_BUF_LEN] __attribute__((aligned(4)));
|
|
|
|
enum {
|
|
UPGRADE_NULL = 0,
|
|
UPGRADE_USB_HARD_KEY,
|
|
UPGRADE_USB_SOFTKEY,
|
|
UPGRADE_UART_SOFT_KEY,
|
|
UPGRADE_UART_ONE_WIRE_HARD_KEY,
|
|
};
|
|
|
|
extern void nvram_set_boot_state(u32 state);
|
|
void chargestore_set_update_ram(void)
|
|
{
|
|
//需要补充设置ram
|
|
int tmp;
|
|
__asm__ volatile("%0 =icfg" : "=r"(tmp));
|
|
tmp &= ~(3 << 8);
|
|
__asm__ volatile("icfg = %0" :: "r"(tmp));//GIE1
|
|
local_irq_disable();
|
|
nvram_set_boot_state(UPGRADE_UART_SOFT_KEY);
|
|
}
|
|
|
|
void __attribute__((weak)) chargestore_data_deal(u8 cmd, u8 *data, u32 len)
|
|
{
|
|
|
|
}
|
|
|
|
void __attribute__((weak)) chargestore_uart_data_deal(u8 *data, u8 len)
|
|
{
|
|
|
|
}
|
|
|
|
static u8 chargestore_get_f95_det_res(u32 equ_res)
|
|
{
|
|
u8 det_res = (equ_res + 50) / 100;
|
|
if (det_res > 0) {
|
|
det_res -= 1;
|
|
}
|
|
if (det_res > 0x0f) {
|
|
det_res = 0x0f;
|
|
}
|
|
return det_res;
|
|
}
|
|
|
|
u8 chargestore_get_det_level(u8 chip_type)
|
|
{
|
|
u32 res = 1600;
|
|
switch (chip_type) {
|
|
case TYPE_F95:
|
|
if (IS_L5V_LOAD_EN()) {
|
|
res = (GET_L5V_RES_DET_S_SEL() + 1) * 50;
|
|
}
|
|
return chargestore_get_f95_det_res(res);
|
|
case TYPE_NORMAL:
|
|
default:
|
|
return 0x0f;
|
|
}
|
|
}
|
|
|
|
static void chargestore_uart_isr_cb(uart_dev uart_num, enum uart_event event)
|
|
{
|
|
s32 rx_len;
|
|
if (event == UART_EVENT_RX_DATA) {
|
|
} else if (event == UART_EVENT_TX_DONE) {
|
|
if (__this->data->io_port == IO_PORT_LDOIN) {
|
|
gpio_set_mode(IO_PORT_SPILT(__this->data->io_port), PORT_INPUT_FLOATING);
|
|
}
|
|
chargestore_data_deal(CMD_COMPLETE, NULL, 0);
|
|
} else if (event == UART_EVENT_RX_TIMEOUT) {
|
|
rx_len = uart_recv_bytes(__this->udev, uart_rx_buf, DMA_BUF_LEN);
|
|
if (rx_len > 0) {
|
|
chargestore_data_deal(CMD_RECVDATA, uart_rx_buf, rx_len);
|
|
chargestore_uart_data_deal(uart_rx_buf, rx_len);
|
|
}
|
|
}
|
|
}
|
|
|
|
void chargestore_write(u8 *data, u8 len)
|
|
{
|
|
if (__this->udev < 0) {
|
|
return;
|
|
}
|
|
if (((u32)data) % 4) {//4byte对齐
|
|
ASSERT(0, "%s: unaligned accesses!", __func__);
|
|
}
|
|
uart_send_bytes(__this->udev, (const void *)data, (u32)len);
|
|
}
|
|
|
|
void chargestore_open(u8 mode)
|
|
{
|
|
s32 ret;
|
|
u32 uart_timeout;
|
|
struct uart_config config = {0};
|
|
struct uart_dma_config dma = {0};
|
|
|
|
#if (TCFG_CHARGE_ENABLE && (TCFG_CHARGESTORE_PORT == IO_PORT_LDOIN))
|
|
if (mode == MODE_RECVDATA) {
|
|
charge_set_ldo5v_detect_stop(0);
|
|
} else {
|
|
charge_set_ldo5v_detect_stop(1);
|
|
}
|
|
#endif
|
|
|
|
if (__this->udev >= 0) {
|
|
return;
|
|
}
|
|
|
|
config.baud_rate = __this->data->baudrate;
|
|
config.tx_pin = __this->data->io_port;
|
|
config.rx_pin = __this->data->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;
|
|
}
|
|
|
|
//如果为VPWR引脚,则关闭驱动开启的上拉
|
|
if (__this->data->io_port == IO_PORT_LDOIN) {
|
|
gpio_set_mode(IO_PORT_SPILT(__this->data->io_port), PORT_INPUT_FLOATING);
|
|
}
|
|
|
|
//确保2byte的时间
|
|
uart_timeout = 25 * 1000000 / __this->data->baudrate;//us
|
|
dma.rx_timeout_thresh = uart_timeout;
|
|
dma.frame_size = DMA_BUF_LEN;
|
|
dma.event_mask = UART_EVENT_RX_DATA | UART_EVENT_RX_TIMEOUT | UART_EVENT_TX_DONE;
|
|
dma.irq_priority = 2;
|
|
dma.irq_callback = chargestore_uart_isr_cb;
|
|
dma.rx_cbuffer = uart_dma_buf;
|
|
dma.rx_cbuffer_size = DMA_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 chargestore_close(void)
|
|
{
|
|
if (__this->udev < 0) {
|
|
return;
|
|
}
|
|
uart_deinit(__this->udev);
|
|
__this->udev = -1;
|
|
#if (TCFG_CHARGE_ENABLE && (TCFG_CHARGESTORE_PORT == IO_PORT_LDOIN))
|
|
charge_set_ldo5v_detect_stop(0);
|
|
#endif
|
|
}
|
|
|
|
void chargestore_set_baudrate(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 chargestore_init(const struct chargestore_platform_data *data)
|
|
{
|
|
__this->data = (struct chargestore_platform_data *)data;
|
|
ASSERT(data);
|
|
__this->udev = -1;
|
|
}
|
|
|
|
#endif
|
|
|