556 lines
17 KiB
C
556 lines
17 KiB
C
|
#include "system/app_core.h"
|
||
|
#include "system/includes.h"
|
||
|
#include "server/server_core.h"
|
||
|
#include "app_config.h"
|
||
|
#include "app_action.h"
|
||
|
#include "vm.h"
|
||
|
#include "update_loader_download.h"
|
||
|
|
||
|
#if(CONFIG_APP_GAMEBOX)
|
||
|
|
||
|
#include "gamebox.h"
|
||
|
|
||
|
#define LOG_TAG_CONST GAMEBOX
|
||
|
#define LOG_TAG "[GAMBOX]"
|
||
|
#define LOG_ERROR_ENABLE
|
||
|
#define LOG_DEBUG_ENABLE
|
||
|
#define LOG_INFO_ENABLE
|
||
|
/* #define LOG_DUMP_ENABLE */
|
||
|
#define LOG_CLI_ENABLE
|
||
|
|
||
|
#include "debug.h"
|
||
|
|
||
|
extern u8 get_jl_update_flag(void);
|
||
|
|
||
|
static void uart_recv_packet();
|
||
|
static void uart_write(const u8 *buffer, u32 len);
|
||
|
static void uart_comm_init();
|
||
|
|
||
|
#define UART_RX_EVENT 0x55410001
|
||
|
#define HEARTBEAT_EVENT 0x55410002
|
||
|
#define HOT_KEY_EVENT 0x55410003
|
||
|
#define TOUCH_POINT
|
||
|
const char hid_report_desc[HID_REPORT_SIZE] = {
|
||
|
0x05, 0x0D, // Usage Page (Digitizer)
|
||
|
0x09, 0x04, // Usage (Touch Screen)
|
||
|
0xA1, 0x01, // Collection (Application)
|
||
|
0x85, TOUCH_SCREEN_ID, // Report ID (1)
|
||
|
0x09, 0x22, // Usage (Finger)
|
||
|
0xA1, 0x02, // Collection (Logical)
|
||
|
0x09, 0x42, // Usage (Tip Switch)
|
||
|
0x09, 0x32, // Usage (In Range)
|
||
|
0x15, 0x00, // Logical Minimum (0)
|
||
|
0x25, 0x01, // Logical Maximum (1)
|
||
|
0x75, 0x01, // Report Size (1)
|
||
|
0x95, 0x02, // Report Count (2)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x95, 0x02, // Report Count (2)
|
||
|
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x09, 0x51, // Usage (Contact Identifier)
|
||
|
0x75, 0x04, // Report Size (4)
|
||
|
0x95, 0x01, // Report Count (1)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||
|
0x75, 0x10, // Report Size (16)
|
||
|
0x95, 0x01, // Report Count (1)
|
||
|
0x09, 0x30, // Usage (X)
|
||
|
0x26, 0xA8, 0x0C, // Logical Maximum (3240)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x09, 0x31, // Usage (Y)
|
||
|
0x26, 0x80, 0x16, // Logical Maximum (5760)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0xC0, // End Collection
|
||
|
0xA1, 0x02, // Collection (Logical)
|
||
|
0x05, 0x0D, // Usage Page (Digitizer)
|
||
|
0x09, 0x42, // Usage (Tip Switch)
|
||
|
0x09, 0x32, // Usage (In Range)
|
||
|
0x15, 0x00, // Logical Minimum (0)
|
||
|
0x25, 0x01, // Logical Maximum (1)
|
||
|
0x75, 0x01, // Report Size (1)
|
||
|
0x95, 0x02, // Report Count (2)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x95, 0x02, // Report Count (2)
|
||
|
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x09, 0x51, // Usage (Contact Identifier)
|
||
|
0x75, 0x04, // Report Size (4)
|
||
|
0x95, 0x01, // Report Count (1)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||
|
0x75, 0x10, // Report Size (16)
|
||
|
0x95, 0x01, // Report Count (1)
|
||
|
0x09, 0x30, // Usage (X)
|
||
|
0x26, 0xA8, 0x0C, // Logical Maximum (3240)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x09, 0x31, // Usage (Y)
|
||
|
0x26, 0x80, 0x16, // Logical Maximum (5760)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0xC0, // End Collection
|
||
|
0xC0, // End Collection
|
||
|
|
||
|
0x05, 0x0D, // Usage Page (Digitizer)
|
||
|
0x09, 0x02, // Usage (Pen)
|
||
|
0xA1, 0x01, // Collection (Application)
|
||
|
0x85, MOUSE_POINT_ID, // Report ID (2)
|
||
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||
|
0x09, 0x01, // Usage (Pointer)
|
||
|
0xA1, 0x00, // Collection (Physical)
|
||
|
0x05, 0x09, // Usage Page (Button)
|
||
|
0x19, 0x01, // Usage Minimum (0x01)
|
||
|
0x29, 0x03, // Usage Maximum (0x03)
|
||
|
0x15, 0x00, // Logical Minimum (0)
|
||
|
0x25, 0x01, // Logical Maximum (1)
|
||
|
0x75, 0x01, // Report Size (1)
|
||
|
0x95, 0x03, // Report Count (3)
|
||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x75, 0x05, // Report Size (5)
|
||
|
0x95, 0x01, // Report Count (1)
|
||
|
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||
|
0x09, 0x30, // Usage (X)
|
||
|
0x09, 0x31, // Usage (Y)
|
||
|
0x09, 0x38, // Usage (Wheel)
|
||
|
0x15, 0x81, // Logical Minimum (-127)
|
||
|
0x25, 0x7F, // Logical Maximum (127)
|
||
|
0x75, 0x08, // Report Size (8)
|
||
|
0x95, 0x03, // Report Count (3)
|
||
|
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||
|
0xC0, // End Collection
|
||
|
0xC0, // End Collection
|
||
|
|
||
|
// 167 bytes
|
||
|
|
||
|
};
|
||
|
#define TASK_NAME "gamebox"
|
||
|
|
||
|
u8 mouse_data_send ;
|
||
|
u8 touch_data_send;
|
||
|
struct mouse_point_t mouse_data;
|
||
|
|
||
|
static u8 is_mouse_point_mode = FALSE;
|
||
|
static u32 cur_work_mode = BT_MODE;
|
||
|
static u32 need_pre_reset = 0;
|
||
|
u32 get_run_mode()
|
||
|
{
|
||
|
/* return UT_DEBUG_MODE; */
|
||
|
/* return BT_MODE; */
|
||
|
/* return USB_MODE; */
|
||
|
/* return UART_MODE; */
|
||
|
return cur_work_mode;
|
||
|
}
|
||
|
void set_run_mode(u32 mode)
|
||
|
{
|
||
|
cur_work_mode = mode;
|
||
|
}
|
||
|
extern u32 get_jl_rcsp_update_status();
|
||
|
static u32 check_ota_mode()
|
||
|
{
|
||
|
if (UPDATE_MODULE_IS_SUPPORT(UPDATE_APP_EN)) {
|
||
|
#if RCSP_UPDATE_EN
|
||
|
if (get_jl_rcsp_update_status()) {
|
||
|
r_printf("OTA ing");
|
||
|
set_run_mode(OTA_MODE);
|
||
|
usb_sie_close_all();//关闭usb
|
||
|
JL_UART1->CON0 = BIT(13) | BIT(12) | BIT(10);//关闭串口
|
||
|
return 1;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void device_insert(const char *dev_name)
|
||
|
{
|
||
|
u32 id = dev_name[strlen(dev_name) - 1] - '0';
|
||
|
log_info("device_insert %s id: %x", dev_name, id);
|
||
|
if (strncmp(dev_name, "hid", 3) == 0) {
|
||
|
hid_process(id);
|
||
|
need_pre_reset = 0;
|
||
|
} else {
|
||
|
|
||
|
#if TCFG_AOA_ENABLE && TCFG_ADB_ENABLE
|
||
|
if (strncmp(dev_name, "adb", 3) == 0) {
|
||
|
if (get_run_mode() == BT_MODE) {
|
||
|
adb_process();
|
||
|
} else {
|
||
|
adb_switch_aoa(id);
|
||
|
}
|
||
|
} else if (strncmp(dev_name, "aoa", 3) == 0) {
|
||
|
u32 succ = aoa_process(1, id);
|
||
|
if (succ) {
|
||
|
set_phone_connect_status(USB_MODE);
|
||
|
} else {
|
||
|
r_printf("aoa error");
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
if (adb_process()) {
|
||
|
usb_h_force_reset(id);
|
||
|
usb_otg_suspend(id, OTG_UNINSTALL);
|
||
|
usb_otg_resume(id);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void heartbeat(void *p)
|
||
|
{
|
||
|
int err = os_taskq_post_msg(TASK_NAME, 1, HEARTBEAT_EVENT);
|
||
|
}
|
||
|
|
||
|
static void gamebox_task(void *arg)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int msg[16];
|
||
|
u8 heartbeat_packet[1] = {0};
|
||
|
|
||
|
key_list_init();
|
||
|
set_run_mode(UT_DEBUG_MODE);
|
||
|
uart_comm_init();
|
||
|
|
||
|
u16 timer_id = sys_timer_add(NULL, heartbeat, 500);
|
||
|
|
||
|
while (1) {
|
||
|
ret = os_taskq_pend("taskq", msg, ARRAY_SIZE(msg));
|
||
|
if (ret != OS_TASKQ) {
|
||
|
continue;
|
||
|
}
|
||
|
if (msg[0] != Q_MSG) {
|
||
|
continue;
|
||
|
}
|
||
|
switch (msg[1]) {
|
||
|
case DEVICE_EVENT_IN:
|
||
|
if (get_run_mode() != OTA_MODE) {
|
||
|
device_insert((const char *)msg[2]);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case UART_RX_EVENT:
|
||
|
/* uart_recv_packet(); */
|
||
|
break;
|
||
|
case HEARTBEAT_EVENT:
|
||
|
heartbeat_packet[0]++;
|
||
|
/* uart_write(heartbeat_packet,1); */
|
||
|
if (check_ota_mode()) {
|
||
|
#if TCFG_PC_ENABLE
|
||
|
usb_stop(0);
|
||
|
#endif
|
||
|
r_printf("%s()", __func__);
|
||
|
sys_timer_del(timer_id);
|
||
|
}
|
||
|
break;
|
||
|
case HOT_KEY_EVENT:
|
||
|
//switch IOS or Android
|
||
|
log_info("hot key %x", msg[2]);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
static void usb_event_handler(struct sys_event *event, void *priv)
|
||
|
{
|
||
|
const char *usb_msg;
|
||
|
usb_dev usb_id;
|
||
|
|
||
|
switch ((u32)event->arg) {
|
||
|
case DEVICE_EVENT_FROM_OTG:
|
||
|
usb_msg = (const char *)event->u.dev.value;
|
||
|
usb_id = usb_msg[2] - '0';
|
||
|
|
||
|
log_debug("usb event : %d DEVICE_EVENT_FROM_OTG %s",
|
||
|
event->u.dev.event, usb_msg);
|
||
|
|
||
|
if (usb_msg[0] == 'h') {
|
||
|
if (event->u.dev.event == DEVICE_EVENT_IN) {
|
||
|
log_info("usb %c online", usb_msg[2]);
|
||
|
if (usb_host_mount(usb_id, 3, 20, 250)) {
|
||
|
usb_h_force_reset(usb_id);
|
||
|
usb_otg_suspend(usb_id, OTG_UNINSTALL);
|
||
|
usb_otg_resume(usb_id);
|
||
|
}
|
||
|
} else if (event->u.dev.event == DEVICE_EVENT_OUT) {
|
||
|
log_info("usb %c offline", usb_msg[2]);
|
||
|
set_phone_connect_status(0);
|
||
|
usb_host_unmount(usb_id);
|
||
|
}
|
||
|
} else if (usb_msg[0] == 's') {
|
||
|
#if TCFG_PC_ENABLE
|
||
|
if (event->u.dev.event == DEVICE_EVENT_IN) {
|
||
|
usb_start(usb_id);
|
||
|
} else {
|
||
|
usb_stop(usb_id);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
case DEVICE_EVENT_FROM_USB_HOST:
|
||
|
log_debug("host_event %x", event->u.dev.event);
|
||
|
if ((event->u.dev.event == DEVICE_EVENT_IN) ||
|
||
|
(event->u.dev.event == DEVICE_EVENT_CHANGE)) {
|
||
|
int err = os_taskq_post_msg(TASK_NAME, 2, DEVICE_EVENT_IN, event->u.dev.value);
|
||
|
if (err) {
|
||
|
r_printf("err %x ", err);
|
||
|
}
|
||
|
} else if (event->u.dev.event == DEVICE_EVENT_OUT) {
|
||
|
log_error("device out %x", event->u.dev.value);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static u16 sys_event_id;
|
||
|
void gamebox_init()
|
||
|
{
|
||
|
register_sys_event_handler(SYS_DEVICE_EVENT, 0, 2, usb_event_handler);
|
||
|
int err = task_create(gamebox_task, NULL, TASK_NAME);
|
||
|
}
|
||
|
|
||
|
struct ut_packet {
|
||
|
char id[4];
|
||
|
|
||
|
u16 type;//USB_CLASS_HID_KEYBOARD : Keyboard MOUSE_POINT_MODE: mouse
|
||
|
|
||
|
union {
|
||
|
struct mouse_data_t m;
|
||
|
struct keyboard_data_t k;
|
||
|
} d;
|
||
|
|
||
|
u16 crc;
|
||
|
|
||
|
} _GNU_PACKED_;
|
||
|
|
||
|
static u8 uart_dma_buffer[256] __attribute__((aligned(4)));
|
||
|
static u8 uart_rxbuf[32];
|
||
|
static u8 uart_txbuf[32] __attribute__((aligned(4)));
|
||
|
|
||
|
static void send2uart(u32 type, const void *p)
|
||
|
{
|
||
|
struct ut_packet *packet = (struct ut_packet *)uart_txbuf;
|
||
|
strcpy(packet[0].id, "HID");
|
||
|
packet[0].type = type;
|
||
|
memcpy(&(packet[0].d), p, sizeof(packet[0].d));
|
||
|
packet[0].crc = CRC16(&packet[0], sizeof(packet[0]) - 2);
|
||
|
|
||
|
packet[1] = packet[0];
|
||
|
|
||
|
/* printf_buf(packet,2*sizeof(*packet)); */
|
||
|
uart_write((u8 *)packet, 2 * sizeof(*packet));
|
||
|
}
|
||
|
|
||
|
static u32 mouse_filter(struct mouse_data_t *p)
|
||
|
{
|
||
|
if (check_ota_mode()) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (p->btn & BIT(2)) { //middle button
|
||
|
is_mouse_point_mode = !is_mouse_point_mode;
|
||
|
point_list_empty();
|
||
|
p->x = 1;
|
||
|
p->y = 1;
|
||
|
p->btn = 0;
|
||
|
return 1;
|
||
|
} else {
|
||
|
return 1; // as mouse event
|
||
|
}
|
||
|
}
|
||
|
void mouse_route(const struct mouse_data_t *p)
|
||
|
{
|
||
|
if (get_run_mode() != UART_MODE) {
|
||
|
if (mouse_filter((void *)p) == 0) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
/* log_info("btn: %x x-y %d %d wheel %d ac_pan %d", */
|
||
|
/* p->btn, p->x, p->y, p->wheel, p->ac_pan); */
|
||
|
switch (get_run_mode()) {
|
||
|
case UART_MODE ://在USB中断函数调用
|
||
|
send2uart(MOUSE_POINT_MODE, p);
|
||
|
break;
|
||
|
case BT_MODE ://在uart中断 或者usb中断函数调用
|
||
|
case USB_MODE://在串口中断调用
|
||
|
if (is_mouse_point_mode) {
|
||
|
send2phone(MOUSE_POINT_MODE, p);
|
||
|
} else {
|
||
|
mouse_mapping(p);
|
||
|
send2phone(TOUCH_SCREEN_MODE, p);
|
||
|
}
|
||
|
break;
|
||
|
case MAPPING_MODE:
|
||
|
send2phone(MOUSE_POINT_MODE + 1, p);
|
||
|
break;
|
||
|
default :
|
||
|
log_info("btn: %x x-y %d %d wheel %d ac_pan %d",
|
||
|
p->btn, p->x, p->y, p->wheel, p->ac_pan);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 keyboard_filter(struct keyboard_data_t *k)
|
||
|
{
|
||
|
if (check_ota_mode()) {
|
||
|
return 0;
|
||
|
}
|
||
|
if ((k->fun_key & _KEY_MOD_LMETA) &&
|
||
|
(k->Keypad[0] == _KEY_F1)) {
|
||
|
os_taskq_post_msg(TASK_NAME, 2, HOT_KEY_EVENT, _KEY_F1);
|
||
|
return 0; //hook this msg
|
||
|
}
|
||
|
return 2;
|
||
|
}
|
||
|
void keyboard_route(const u8 *p)
|
||
|
{
|
||
|
/* log_info("keyboard:"); */
|
||
|
/* printf_buf(p, 8); */
|
||
|
if (keyboard_filter((struct keyboard_data_t *)p) == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
switch (get_run_mode()) {
|
||
|
case UART_MODE ://在USB中断函数调用
|
||
|
send2uart(KEYBOARD_MODE, p);
|
||
|
break;
|
||
|
case BT_MODE ://在uart接收事件 或者usb中断函数调用
|
||
|
case USB_MODE://在串口事件调用
|
||
|
key_mapping((const void *)p);
|
||
|
send2phone(TOUCH_SCREEN_MODE, p);
|
||
|
break;
|
||
|
case MAPPING_MODE:
|
||
|
send2phone(KEYBOARD_MODE, p);
|
||
|
break;
|
||
|
default :
|
||
|
printf_buf((u8 *)p, 8);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static volatile u32 tx_idle;
|
||
|
static KFIFO uart_fifo;
|
||
|
|
||
|
SET_INTERRUPT
|
||
|
static void uart_isr(void)
|
||
|
{
|
||
|
u32 rx_len;
|
||
|
if ((JL_UART1->CON0 & BIT(2)) && (JL_UART1->CON0 & BIT(15))) {
|
||
|
JL_UART1->CON0 |= BIT(13);
|
||
|
tx_idle = 1;
|
||
|
}
|
||
|
if ((JL_UART1->CON0 & BIT(3)) && (JL_UART1->CON0 & BIT(14))) {
|
||
|
JL_UART1->CON0 |= BIT(12); //清RX PND
|
||
|
}
|
||
|
|
||
|
if ((JL_UART1->CON0 & BIT(5)) && (JL_UART1->CON0 & BIT(11))) {
|
||
|
//OTCNT PND
|
||
|
JL_UART1->CON0 |= BIT(7); //DMA模式
|
||
|
JL_UART1->CON0 |= BIT(10); //清OTCNT PND
|
||
|
JL_UART1->CON0 |= BIT(12); //清RX PND(这里的顺序不能改变,这里要清一次)
|
||
|
rx_len = JL_UART1->HRXCNT; //读当前串口接收数据的个数
|
||
|
|
||
|
if (rx_len) {
|
||
|
uart_fifo.buf_in += rx_len;
|
||
|
uart_recv_packet();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void uart_comm_init()
|
||
|
{
|
||
|
request_irq(IRQ_UART1_IDX, 2, uart_isr, 0);//优先级不能比usb低
|
||
|
|
||
|
uart_fifo.buffer = uart_dma_buffer;
|
||
|
uart_fifo.buf_size = sizeof(uart_dma_buffer);
|
||
|
uart_fifo.buf_in = uart_fifo.buf_out = 0;
|
||
|
|
||
|
gpio_set_uart1(-1);
|
||
|
|
||
|
gpio_output_channle(IO_PORTB_08, CH1_UT1_TX);
|
||
|
gpio_uart_rx_input(IO_PORTB_09, 1, 1);
|
||
|
gpio_set_pull_up(IO_PORTB_08, 1);
|
||
|
|
||
|
JL_UART1->CON0 = BIT(13) | BIT(12) | BIT(10);
|
||
|
|
||
|
JL_UART1->RXSADR = (u32)uart_fifo.buffer;
|
||
|
JL_UART1->RXEADR = (u32)(uart_fifo.buffer + uart_fifo.buf_size);
|
||
|
JL_UART1->RXCNT = uart_fifo.buf_size / 2;
|
||
|
JL_UART1->OTCNT = 100 * (clk_get("lsb") / 1000000);
|
||
|
|
||
|
JL_UART1->BAUD = (clk_get("uart") / 2000000) / 4 - 1;
|
||
|
|
||
|
JL_UART1->CON0 |= BIT(6) | BIT(5) | BIT(3);
|
||
|
JL_UART1->CON0 |= BIT(0);
|
||
|
|
||
|
memset(uart_txbuf, cur_work_mode, 32);
|
||
|
}
|
||
|
|
||
|
static u32 kfifo_get(KFIFO *kfifo, u8 *buffer, u32 len)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
len = MIN(len, kfifo->buf_in - kfifo->buf_out);
|
||
|
|
||
|
i = MIN(len, kfifo->buf_size - (kfifo->buf_out & (kfifo->buf_size - 1)));
|
||
|
|
||
|
memcpy(buffer, kfifo->buffer + (kfifo->buf_out & (kfifo->buf_size - 1)), i);
|
||
|
|
||
|
memcpy(buffer + i, kfifo->buffer, len - i);
|
||
|
|
||
|
kfifo->buf_out += len;
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
static u32 uart_read(u8 *buffer, u32 len)
|
||
|
{
|
||
|
return kfifo_get(&uart_fifo, buffer, len);
|
||
|
}
|
||
|
|
||
|
static void uart_write(const u8 *buffer, u32 len)
|
||
|
{
|
||
|
tx_idle = 0;
|
||
|
JL_UART1->CON0 |= BIT(13);
|
||
|
JL_UART1->CON0 |= BIT(2);
|
||
|
JL_UART1->TXADR = (u32)buffer;
|
||
|
JL_UART1->TXCNT = len;
|
||
|
while (!tx_idle) {
|
||
|
asm("idle");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
static void uart_recv_packet()
|
||
|
{
|
||
|
struct ut_packet *p;
|
||
|
memset(uart_rxbuf, 0, sizeof(uart_rxbuf));
|
||
|
|
||
|
u8 *u = uart_rxbuf;
|
||
|
u8 len;
|
||
|
|
||
|
__r0:
|
||
|
len = uart_read(u, sizeof(uart_rxbuf));
|
||
|
if (len < sizeof(*p)) {
|
||
|
return;
|
||
|
}
|
||
|
__r1:
|
||
|
p = (struct ut_packet *)strstr((const char *)u, "HID");
|
||
|
if (p) {
|
||
|
if (p->crc == CRC16(p, sizeof(*p) - 2)) {
|
||
|
if (p->type == MOUSE_POINT_MODE) {
|
||
|
mouse_route(&p->d.m);
|
||
|
} else if (p->type == KEYBOARD_MODE) {
|
||
|
keyboard_route((const u8 *)&p->d.m);
|
||
|
}
|
||
|
goto __r0;
|
||
|
/* return; */
|
||
|
}
|
||
|
} else {
|
||
|
p = (struct ut_packet *)strstr((const char *)u, "UPDATE");//reset 进入uboot模式
|
||
|
}
|
||
|
|
||
|
if (u < &uart_rxbuf[sizeof(*p)]) {
|
||
|
u += sizeof(*p);
|
||
|
goto __r1;
|
||
|
}
|
||
|
goto __r0;
|
||
|
}
|
||
|
|
||
|
#endif
|