#include "drv_usart.h" #include "app_rs485_1.h" #include "app_can.h" #include "drv_can.h" static u16 shark_uart_poll_ticks; static u8 shark_uart_poll_index; static void shark_uart_gpio_init(void) { /* enable GPIO clock */ rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_AF); rcu_periph_clock_enable(RCU_USART0); rcu_periph_clock_enable(RCU_USART1); /* connect port to USARTx_Tx */ gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2 | GPIO_PIN_9); /* connect port to USARTx_Rx */ gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3 | GPIO_PIN_10); } static void shark_uart_irq_init(void) { nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0); nvic_irq_enable(USART0_IRQn, 1, 0); nvic_irq_enable(USART1_IRQn, 1, 0); } static void shark_uart_dev_init(SUB_BMS_INFO *info) { usart_deinit(info->uart); usart_baudrate_set(info->uart, USART_BAUND); usart_word_length_set(info->uart, USART_WL_8BIT); usart_stop_bit_set(info->uart, USART_STB_1BIT); usart_parity_config(info->uart, USART_PM_NONE); usart_hardware_flow_rts_config(info->uart, USART_RTS_DISABLE); usart_hardware_flow_cts_config(info->uart, USART_CTS_DISABLE); usart_receive_config(info->uart, USART_RECEIVE_ENABLE); usart_transmit_config(info->uart, USART_TRANSMIT_ENABLE); usart_interrupt_enable(info->uart, USART_INT_RBNE); usart_enable(info->uart); } static void shark_uart_isr(SUB_BMS_INFO *info) { if (usart_flag_get(info->uart, USART_FLAG_RBNE) != RESET) { u8 value = usart_data_receive(info->uart); if (info->rx_length < sizeof(info->rx_buff)) { info->rx_buff[info->rx_length] = value; info->rx_length++; info->rx_busy = 5; } else { info->rx_busy = 0; info->rx_pending = shark_true; } } if (usart_flag_get(info->uart, USART_FLAG_TC) != RESET) { if (info->tx_index < info->tx_length) { usart_data_transmit(info->uart, info->tx_buff[info->tx_index]); info->tx_index++; } else { usart_interrupt_disable(info->uart, USART_INT_TC); } } } void shark_uart_init(void) { shark_uart_gpio_init(); shark_uart_dev_init(&sub_bms_info_1); shark_uart_dev_init(&sub_bms_info_2); shark_uart_irq_init(); } u16 shark_uart_read(SUB_BMS_INFO *info, u8 *buff, u8 length) { if (info->rx_length == 0) { return 0; } if (length > info->rx_length) { length = info->rx_length; } memcpy(buff, info->rx_buff, length); info->rx_pending = shark_false; info->rx_length = 0; return length; } void shark_uart_write(SUB_BMS_INFO *info, u16 size) { info->tx_index = 0; info->tx_length = size; info->tx_busy = CONFIG_UART_TIMEOUT; usart_interrupt_enable(info->uart, USART_INT_TC); } shark_bool shark_uart_write2(SUB_BMS_INFO *info, const u8 *buff, u16 size) { if (size > sizeof(info->tx_buff)) { return shark_false; } memcpy(info->tx_buff, buff, size); shark_uart_write(info, size); return shark_true; } int8_t Send_Data_RS485(uint8_t *data, uint16_t size) { return shark_uart_write2(&sub_bms_info_1, data, size); } uint16_t Get_RS485_Data(uint8_t * dbuf, uint16_t dbuf_len) { return shark_uart_read(&sub_bms_info_1, dbuf, dbuf_len); } static void shark_uart_disconnect(SUB_BMS_INFO *info) { shark_battery_clear(info); } static void shark_uart_tick_raw(SUB_BMS_INFO *info) { if (info->rx_busy > 0) { if (info->rx_busy > 1) { info->rx_busy--; } else { info->rx_busy = 0; info->rx_pending = shark_true; } } if (info->send_state == SHARK_SEND_PENDING) { if (info->tx_busy > 0) { info->tx_busy--; } else { info->send_state = SHARK_SEND_TIMEOUT; if (info->connected > 0) { if (info->connected > 1) { info->connected--; info->tx_pending = shark_true; } else { info->connected = 0; shark_uart_disconnect(info); } } } } if (info->update_ticks == 0 && info->connected) { info->update_mask = 0xFF; } info->update_ticks++; } void shark_uart_tick(void) { if (shark_uart_poll_ticks < (CONFIG_UART_POLL_DELAY / 2)) { shark_uart_poll_ticks++; } else { shark_uart_poll_ticks = 0; shark_uart_poll_index++; if ((shark_uart_poll_index & 1) == 0) { sub_bms_info_1.tx_pending = shark_true; } else { sub_bms_info_2.tx_pending = shark_true; } } shark_uart_tick_raw(&sub_bms_info_1); shark_uart_tick_raw(&sub_bms_info_2); } void shark_uart_poll_raw(SUB_BMS_INFO *info) { if (info->rx_pending) { info->rx_pending = shark_false; shark_battery_process(info, info->rx_buff, info->rx_length); info->rx_length = 0; } if (info->tx_pending) { info->tx_pending = shark_false; if (!shark_battery_switch_busy) { shark_battery_send_command(info); } } } void shark_uart_poll(void) { shark_uart_poll_raw(&sub_bms_info_1); shark_uart_poll_raw(&sub_bms_info_2); } void shark_uart_poll_safe(void) { fwdgt_counter_reload(); Handle_Can_Data(); shark_uart_poll(); shark_can_tx_flush(); } void USART0_IRQHandler(void) { shark_uart_isr(&sub_bms_info_1); } void USART1_IRQHandler(void) { shark_uart_isr(&sub_bms_info_2); }