/* Copyright 2023 @ Nuphy This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "ansi.h" #include "uart.h" // qmk uart.h USART_MGR_STRUCT Usart_Mgr; #define RX_SBYTE Usart_Mgr.RXDBuf[0] #define RX_CMD Usart_Mgr.RXDBuf[1] #define RX_ACK Usart_Mgr.RXDBuf[2] #define RX_LEN Usart_Mgr.RXDBuf[3] #define RX_DAT Usart_Mgr.RXDBuf[4] bool f_uart_ack = 0; bool f_rf_read_data_ok = 0; bool f_rf_sts_sysc_ok = 0; bool f_rf_new_adv_ok = 0; bool f_rf_reset = 0; bool f_rf_hand_ok = 0; bool f_goto_sleep = 0; bool f_wakeup_prepare = 0; uint8_t uart_bit_report_buf[32] = {0}; uint8_t func_tab[32] = {0}; uint8_t bitkb_report_buf[32] = {0}; uint8_t bytekb_report_buf[8] = {0}; uint8_t mouse_report_buf[5] = {0}; uint16_t conkb_report = 0; uint16_t syskb_report = 0; uint8_t sync_lost = 0; uint8_t disconnect_delay = 0; extern DEV_INFO_STRUCT dev_info; extern host_driver_t *m_host_driver; extern uint8_t host_mode; extern uint8_t rf_blink_cnt; extern uint16_t rf_link_show_time; extern uint16_t rf_linking_time; extern uint16_t no_act_time; extern bool f_send_channel; extern bool f_dial_sw_init_ok; report_mouse_t mousekey_get_report(void); void uart_init(uint32_t baud); // qmk uart.c void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size); void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length); uint8_t get_checksum(uint8_t *buf, uint8_t len); void uart_receive_pro(void); void break_all_key(void); uint16_t host_last_consumer_usage(void); /** * @brief Uart send consumer keys report. * @note Call in host.c */ void uart_send_consumer_report(void) { no_act_time = 0; conkb_report = host_last_consumer_usage(); uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&conkb_report), 2); } /** * @brief Uart send mouse keys report. * @note Call in host.c */ void uart_send_mouse_report(void) { report_mouse_t mouse_report = mousekey_get_report(); no_act_time = 0; memcpy(mouse_report_buf, &mouse_report.buttons, 5); uart_send_report(CMD_RPT_MS, mouse_report_buf, 5); } /** * @brief Uart send system keys report. * @note Call in host.c */ void uart_send_system_report(void) { no_act_time = 0; syskb_report = host_last_system_usage(); uart_send_report(CMD_RPT_SYS, (uint8_t *)(&syskb_report), 2); } /** * @brief Uart auto nkey send */ bool f_f_bit_kb_act = 0; static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8_t size) { uint8_t i, j, byte_index; uint8_t change_mask, offset_mask; uint8_t key_code = 0; bool f_byte_send = 0, f_bit_send = 0; if (pre_bit_report[0] ^ now_bit_report[0]) { bytekb_report_buf[0] = now_bit_report[0]; f_byte_send = 1; } for (i = 1; i < size; i++) { change_mask = pre_bit_report[i] ^ now_bit_report[i]; offset_mask = 1; for (j = 0; j < 8; j++) { if (change_mask & offset_mask) { if (now_bit_report[i] & offset_mask) { for (byte_index = 2; byte_index < 8; byte_index++) { if (bytekb_report_buf[byte_index] == 0) { bytekb_report_buf[byte_index] = key_code; f_byte_send = 1; break; } } if (byte_index >= 8) { uart_bit_report_buf[i] |= offset_mask; f_bit_send = 1; } } else { for (byte_index = 2; byte_index < 8; byte_index++) { if (bytekb_report_buf[byte_index] == key_code) { bytekb_report_buf[byte_index] = 0; f_byte_send = 1; break; ; } } if (byte_index >= 8) { uart_bit_report_buf[i] &= ~offset_mask; f_bit_send = 1; } } } key_code++; offset_mask <<= 1; } } if (f_bit_send) { f_f_bit_kb_act = 1; uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16); } if (f_byte_send) { uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8); } } /** * @brief Uart send keys report. * @note Call in host.c */ void uart_send_report_func(void) { static uint32_t interval_timer = 0; if (dev_info.link_mode == LINK_USB) return; keyboard_protocol = 1; if(keymap_config.nkro) nkro_report->mods = get_mods() | get_weak_mods(); if ((dev_info.sys_sw_state == SYS_SW_MAC) && (memcmp(bytekb_report_buf, &keyboard_report->mods, 8))) { no_act_time = 0; keyboard_report->reserved = 0; memcpy(bytekb_report_buf, &keyboard_report->mods, 8); uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8); } else if ((dev_info.sys_sw_state == SYS_SW_WIN) && (memcmp(bitkb_report_buf, &nkro_report->mods, NKRO_REPORT_BITS+1))) { no_act_time = 0; uart_auto_nkey_send(bitkb_report_buf, &nkro_report->mods, NKRO_REPORT_BITS+1); memcpy(&bitkb_report_buf[0], &nkro_report->mods, NKRO_REPORT_BITS+1); } else if (timer_elapsed32(interval_timer) > 100) { interval_timer = timer_read32(); if (no_act_time <= 200) { uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8); if(f_f_bit_kb_act) uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16); } else { f_f_bit_kb_act = 0; } } } /** * @brief Parsing the data received from the RF module. */ void RF_Protocol_Receive(void) { uint8_t i, check_sum = 0; if (Usart_Mgr.RXDState == RX_Done) { f_uart_ack = 1; sync_lost = 0; if (Usart_Mgr.RXDLen > 4) { for (i = 0; i < RX_LEN; i++) check_sum += Usart_Mgr.RXDBuf[4 + i]; if (check_sum != Usart_Mgr.RXDBuf[4 + i]) { Usart_Mgr.RXDState = RX_SUM_ERR; return; } } else if (Usart_Mgr.RXDLen == 3) { if (Usart_Mgr.RXDBuf[2] == 0xA0) { f_uart_ack = 1; } } switch (RX_CMD) { case CMD_HAND: { f_rf_hand_ok = 1; break; } case CMD_24G_SUSPEND: { f_goto_sleep = 1; break; } case CMD_NEW_ADV: { f_rf_new_adv_ok = 1; break; } case CMD_RF_STS_SYSC: { static uint8_t error_cnt = 0; if (dev_info.link_mode == Usart_Mgr.RXDBuf[4]) { error_cnt = 0; dev_info.rf_state = Usart_Mgr.RXDBuf[5]; if ((dev_info.rf_state == RF_CONNECT) && ((Usart_Mgr.RXDBuf[6] & 0xf8) == 0)) { dev_info.rf_led = Usart_Mgr.RXDBuf[6]; } dev_info.rf_charge = Usart_Mgr.RXDBuf[7]; if (Usart_Mgr.RXDBuf[8] <= 100) dev_info.rf_baterry = Usart_Mgr.RXDBuf[8]; if (dev_info.rf_charge & 0x01) dev_info.rf_baterry = 100; } else { if (dev_info.rf_state != RF_INVAILD) { if (error_cnt >= 5) { error_cnt = 0; f_send_channel = 1; } else { error_cnt++; } } } f_rf_sts_sysc_ok = 1; break; } case CMD_READ_DATA: { memcpy(func_tab, &Usart_Mgr.RXDBuf[4], 32); if (func_tab[4] <= LINK_USB) { dev_info.link_mode = func_tab[4]; } if (func_tab[5] < LINK_USB) { dev_info.rf_channel = func_tab[5]; } if ((func_tab[6] <= LINK_BT_3) && (func_tab[6] >= LINK_BT_1)) { dev_info.ble_channel = func_tab[6]; } f_rf_read_data_ok = 1; break; } } Usart_Mgr.RXDLen = 0; Usart_Mgr.RXDState = RX_Idle; Usart_Mgr.RXDOverTime = 0; } } /** * @brief Uart send cmd. * @param cmd: cmd. * @param wait_ack: wait time for ack after sending. * @param delayms: delay before sending. */ uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms) { wait_ms(delayms); memset(&Usart_Mgr.TXDBuf[0], 0, UART_MAX_LEN); Usart_Mgr.TXDBuf[0] = UART_HEAD; Usart_Mgr.TXDBuf[1] = cmd; Usart_Mgr.TXDBuf[2] = 0x00; switch (cmd) { case CMD_SLEEP: { Usart_Mgr.TXDBuf[3] = 1; Usart_Mgr.TXDBuf[4] = 0; Usart_Mgr.TXDBuf[5] = 0; break; } case CMD_HAND: { Usart_Mgr.TXDBuf[3] = 1; Usart_Mgr.TXDBuf[4] = 0; Usart_Mgr.TXDBuf[5] = 0; break; } case CMD_RF_STS_SYSC: { Usart_Mgr.TXDBuf[3] = 1; Usart_Mgr.TXDBuf[4] = dev_info.link_mode; Usart_Mgr.TXDBuf[5] = dev_info.link_mode; break; } case CMD_SET_LINK: { dev_info.rf_state = RF_LINKING; Usart_Mgr.TXDBuf[3] = 1; Usart_Mgr.TXDBuf[4] = dev_info.link_mode; Usart_Mgr.TXDBuf[5] = dev_info.link_mode; rf_linking_time = 0; disconnect_delay = 0xff; break; } case CMD_NEW_ADV: { dev_info.rf_state = RF_PAIRING; Usart_Mgr.TXDBuf[3] = 2; Usart_Mgr.TXDBuf[4] = dev_info.link_mode; Usart_Mgr.TXDBuf[5] = 1; Usart_Mgr.TXDBuf[6] = dev_info.link_mode + 1; rf_linking_time = 0; disconnect_delay = 0xff; f_rf_new_adv_ok = 0; break; } case CMD_CLR_DEVICE: { Usart_Mgr.TXDBuf[3] = 1; Usart_Mgr.TXDBuf[4] = 0; Usart_Mgr.TXDBuf[5] = 0; break; } case CMD_SET_CONFIG: { Usart_Mgr.TXDBuf[3] = 1; Usart_Mgr.TXDBuf[4] = POWER_DOWN_DELAY; Usart_Mgr.TXDBuf[5] = POWER_DOWN_DELAY; break; } case CMD_SET_NAME: { Usart_Mgr.TXDBuf[3] = 17; Usart_Mgr.TXDBuf[4] = 1; Usart_Mgr.TXDBuf[5] = 15; Usart_Mgr.TXDBuf[6] = 'N'; Usart_Mgr.TXDBuf[7] = 'u'; Usart_Mgr.TXDBuf[8] = 'P'; Usart_Mgr.TXDBuf[9] = 'h'; Usart_Mgr.TXDBuf[10] = 'y'; Usart_Mgr.TXDBuf[11] = ' '; Usart_Mgr.TXDBuf[12] = 'A'; Usart_Mgr.TXDBuf[13] = 'i'; Usart_Mgr.TXDBuf[14] = 'r'; Usart_Mgr.TXDBuf[15] = '7'; Usart_Mgr.TXDBuf[16] = '5'; Usart_Mgr.TXDBuf[17] = ' '; Usart_Mgr.TXDBuf[18] = 'V'; Usart_Mgr.TXDBuf[19] = '2'; Usart_Mgr.TXDBuf[20] = '-'; Usart_Mgr.TXDBuf[21] = get_checksum(Usart_Mgr.TXDBuf + 4, Usart_Mgr.TXDBuf[3]); break; } case CMD_READ_DATA: { Usart_Mgr.TXDBuf[3] = 2; Usart_Mgr.TXDBuf[4] = 0x00; Usart_Mgr.TXDBuf[5] = FUNC_VALID_LEN; Usart_Mgr.TXDBuf[6] = FUNC_VALID_LEN; break; } case CMD_RF_DFU: { Usart_Mgr.TXDBuf[3] = 1; Usart_Mgr.TXDBuf[4] = 0; Usart_Mgr.TXDBuf[5] = 0; break; } default: break; } f_uart_ack = 0; UART_Send_Bytes(Usart_Mgr.TXDBuf, Usart_Mgr.TXDBuf[3] + 5); if (wait_ack) { while (wait_ack--) { wait_ms(1); if (f_uart_ack) return TX_OK; } } else { return TX_OK; } return TX_TIMEOUT; } /** * @brief RF module state sync. */ void dev_sts_sync(void) { static uint32_t interval_timer = 0; static uint8_t link_state_temp = RF_DISCONNECT; if (timer_elapsed32(interval_timer) < 200) return; else interval_timer = timer_read32(); if (f_rf_reset) { f_rf_reset = 0; wait_ms(100); writePinLow(NRF_RESET_PIN); wait_ms(50); writePinHigh(NRF_RESET_PIN); wait_ms(50); } else if (f_send_channel) { f_send_channel = 0; uart_send_cmd(CMD_SET_LINK, 10, 10); } if (dev_info.link_mode == LINK_USB) { if (host_mode != HOST_USB_TYPE) { host_mode = HOST_USB_TYPE; host_set_driver(m_host_driver); break_all_key(); } rf_blink_cnt = 0; } else { if (host_mode != HOST_RF_TYPE) { host_mode = HOST_RF_TYPE; break_all_key(); host_set_driver(0); } if (dev_info.rf_state != RF_CONNECT) { if (disconnect_delay >= 10) { rf_blink_cnt = 3; rf_link_show_time = 0; link_state_temp = dev_info.rf_state; } else { disconnect_delay++; } } else if (dev_info.rf_state == RF_CONNECT) { rf_linking_time = 0; disconnect_delay = 0; rf_blink_cnt = 0; if (link_state_temp != RF_CONNECT) { link_state_temp = RF_CONNECT; rf_link_show_time = 0; } } } uart_send_cmd(CMD_RF_STS_SYSC, 1, 1); if (dev_info.link_mode != LINK_USB) { if (++sync_lost >= 5) { sync_lost = 0; f_rf_reset = 1; } } } /** * @brief Uart send bytes. * @param Buffer data buf * @param Length data lenght */ void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length) { writePinLow(NRF_WAKEUP_PIN); wait_us(50); uart_transmit(Buffer, Length); wait_us(50 + Length * 30); writePinHigh(NRF_WAKEUP_PIN); } /** * @brief get checksum. * @param buf data buf * @param len data lenght */ uint8_t get_checksum(uint8_t *buf, uint8_t len) { uint8_t i; uint8_t checksum = 0; for (i = 0; i < len; i++) checksum += *buf++; checksum ^= UART_HEAD; return checksum; } /** * @brief Uart send report. * @param report_type report_type * @param report_buf report_buf * @param report_size report_size */ void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size) { if (f_dial_sw_init_ok == 0) return; if (dev_info.link_mode == LINK_USB) return; if (dev_info.rf_state != RF_CONNECT) return; Usart_Mgr.TXDBuf[0] = UART_HEAD; Usart_Mgr.TXDBuf[1] = report_type; Usart_Mgr.TXDBuf[2] = 0x01; Usart_Mgr.TXDBuf[3] = report_size; memcpy(&Usart_Mgr.TXDBuf[4], report_buf, report_size); Usart_Mgr.TXDBuf[4 + report_size] = get_checksum(&Usart_Mgr.TXDBuf[4], report_size); UART_Send_Bytes(&Usart_Mgr.TXDBuf[0], report_size + 5); wait_us(200); } /** * @brief Uart receives data and processes it after completion,. */ void uart_receive_pro(void) { static bool rcv_start = false; // Receiving serial data from RF module while (uart_available()) { rcv_start = true; if (Usart_Mgr.RXDLen >= UART_MAX_LEN) { uart_read(); } else { Usart_Mgr.RXDBuf[Usart_Mgr.RXDLen++] = uart_read(); } if (!uart_available()) { wait_us(200); } } // Processing received serial port protocol if (rcv_start) { rcv_start = false; Usart_Mgr.RXDState = RX_Done; RF_Protocol_Receive(); Usart_Mgr.RXDLen = 0; } } /** * @brief RF uart initial. */ void rf_uart_init(void) { /* set uart buad as 460800 */ uart_init(460800); /* Enable parity check */ USART1->CR1 &= ~((uint32_t)USART_CR1_UE); USART1->CR1 |= USART_CR1_M0 | USART_CR1_PCE; USART1->CR1 |= USART_CR1_UE; /* set Rx and Tx pin pull up */ GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7); GPIOB->PUPDR |= (GPIO_PUPDR_PUPDR6_0 | GPIO_PUPDR_PUPDR7_0); } /** * @brief RF module initial. */ void rf_device_init(void) { uint8_t timeout = 0; void uart_receive_pro(void); timeout = 10; f_rf_hand_ok = 0; while (timeout--) { uart_send_cmd(CMD_HAND, 0, 20); wait_ms(5); uart_receive_pro(); // receive data uart_receive_pro(); // parsing data if (f_rf_hand_ok) break; } timeout = 10; f_rf_read_data_ok = 0; while (timeout--) { uart_send_cmd(CMD_READ_DATA, 0, 20); wait_ms(5); uart_receive_pro(); uart_receive_pro(); if (f_rf_read_data_ok) break; } timeout = 10; f_rf_sts_sysc_ok = 0; while (timeout--) { uart_send_cmd(CMD_RF_STS_SYSC, 0, 20); wait_ms(5); uart_receive_pro(); uart_receive_pro(); if (f_rf_sts_sysc_ok) break; } uart_send_cmd(CMD_SET_NAME, 10, 20); }