#include "s600_turn_key.h" #include "ws2818_spi.h" #include "s600_uart.h" #include "s600_can.h" #include "s600_pwm.h" #include "s600_adc.h" #include "s600_dac.h" #include "string.h" #include "stdlib.h" #define S600_UART0_com USART0 #if CONFIG_UART_MAIN == 0 #define S600_UART0_baudrate 500000 #else #define S600_UART0_baudrate 115200 #endif #define S600_UART0_tx_port GPIOA #define S600_UART0_tx_pin GPIO_PIN_9 #define S600_UART0_rx_port GPIOA #define S600_UART0_rx_pin GPIO_PIN_10 #define S600_UART0_irq USART0_IRQn #define S600_UART0_clk RCU_USART0 #define S600_UART0_tx_gpio_clk RCU_GPIOA #define S600_UART0_rx_gpio_clk RCU_GPIOA #define S600_UART0_tx_dma DMA0 #define S600_UART0_tx_dma_ch DMA_CH3 #define S600_UART0_tx_dma_clk RCU_DMA0 #define S600_UART0_rx_dma DMA0 #define S600_UART0_rx_dma_ch DMA_CH4 #define S600_UART0_rx_dma_clk RCU_DMA0 #define S600_UART0_on_data_received s600_uart0_received #define S600_UART1_com USART1 #if CONFIG_UART_MAIN == 1 #define S600_UART1_baudrate 500000 #else #define S600_UART1_baudrate 115200 #endif #define S600_UART1_tx_port GPIOA #define S600_UART1_tx_pin GPIO_PIN_2 #define S600_UART1_rx_port GPIOA #define S600_UART1_rx_pin GPIO_PIN_3 #define S600_UART1_irq USART1_IRQn #define S600_UART1_clk RCU_USART1 #define S600_UART1_tx_gpio_clk RCU_GPIOA #define S600_UART1_rx_gpio_clk RCU_GPIOA #define S600_UART1_tx_dma DMA0 #define S600_UART1_tx_dma_ch DMA_CH6 #define S600_UART1_tx_dma_clk RCU_DMA0 #define S600_UART1_rx_dma DMA0 #define S600_UART1_rx_dma_ch DMA_CH5 #define S600_UART1_rx_dma_clk RCU_DMA0 #define S600_UART1_on_data_received s600_uart1_received #define S600_UART2_com USART2 #define S600_UART2_baudrate 115200 #define S600_UART2_tx_port GPIOB #define S600_UART2_tx_pin GPIO_PIN_10 #define S600_UART2_rx_port GPIOB #define S600_UART2_rx_pin GPIO_PIN_11 #define S600_UART2_irq USART2_IRQn #define S600_UART2_clk RCU_USART2 #define S600_UART2_tx_gpio_clk RCU_GPIOB #define S600_UART2_rx_gpio_clk RCU_GPIOB #define S600_UART2_tx_dma DMA0 #define S600_UART2_tx_dma_ch DMA_CH1 #define S600_UART2_tx_dma_clk RCU_DMA0 #define S600_UART2_rx_dma DMA0 #define S600_UART2_rx_dma_ch DMA_CH2 #define S600_UART2_rx_dma_clk RCU_DMA0 #define S600_UART2_on_data_received s600_uart2_received #define S600_UART3_com UART3 #define S600_UART3_baudrate 115200 #define S600_UART3_tx_port GPIOC #define S600_UART3_tx_pin GPIO_PIN_10 #define S600_UART3_rx_port GPIOC #define S600_UART3_rx_pin GPIO_PIN_11 #define S600_UART3_irq UART3_IRQn #define S600_UART3_clk RCU_UART3 #define S600_UART3_tx_gpio_clk RCU_GPIOC #define S600_UART3_rx_gpio_clk RCU_GPIOC #define S600_UART3_tx_dma DMA1 #define S600_UART3_tx_dma_ch DMA_CH4 #define S600_UART3_tx_dma_clk RCU_DMA1 #define S600_UART3_rx_dma DMA1 #define S600_UART3_rx_dma_ch DMA_CH2 #define S600_UART3_rx_dma_clk RCU_DMA1 #define S600_UART3_on_data_received s600_uart3_received #define S600_UART4_com UART4 #define S600_UART4_baudrate 38400 #define S600_UART4_tx_port GPIOC #define S600_UART4_tx_pin GPIO_PIN_12 #define S600_UART4_rx_port GPIOD #define S600_UART4_rx_pin GPIO_PIN_2 #define S600_UART4_irq UART4_IRQn #define S600_UART4_clk RCU_UART4 #define S600_UART4_tx_gpio_clk RCU_GPIOC #define S600_UART4_rx_gpio_clk RCU_GPIOD #define S600_UART4_on_data_received s600_uart4_received // ================================================================================ #define S600_UART_CACHE_SIZE \ ((S600_UART_TX_MEM_SIZE + S600_UART_RX_MEM_SIZE) * (S600_UART_COUNT - 1) + S600_UART_MAIN_TX_MEM_SIZE + S600_UART_MAIN_RX_MEM_SIZE) #define S600_UART_DMA_ADDR(index) \ (S600_UART##index##_com + 0x04) #define S600_UART_DMA_CHCTL_TX(uart) \ DMA_CHCTL(uart->tx_dma, uart->tx_dma_ch) #define S600_UART_DMA_CHCNT_TX(uart) \ DMA_CHCNT(uart->tx_dma, uart->tx_dma_ch) #define S600_UART_DMA_CHMADDR_TX(uart) \ DMA_CHMADDR(uart->tx_dma, uart->tx_dma_ch) #define S600_UART_DMA_CHCTL_RX(uart) \ DMA_CHCTL(uart->rx_dma, uart->rx_dma_ch) #define S600_UART_DMA_CHCNT_RX(uart) \ DMA_CHCNT(uart->rx_dma, uart->rx_dma_ch) #define S600_UART_DMA_CHMADDR_RX(uart) \ DMA_CHMADDR(uart->rx_dma, uart->rx_dma_ch) #define S600_UART_DEVICE_INIT(index) \ do { \ s600_uarts[index].com = S600_UART##index##_com; \ s600_uarts[index].on_data_received = S600_UART##index##_on_data_received; \ byte_queue_init(&s600_uarts[index].tx_queue, s600_uarts[index].tx_cache, s600_uarts[index].tx_cache_size); \ byte_queue_init(&s600_uarts[index].rx_queue, s600_uarts[index].rx_cache, s600_uarts[index].rx_cache_size); \ rcu_periph_clock_enable(S600_UART##index##_clk); \ rcu_periph_clock_enable(S600_UART##index##_rx_gpio_clk); \ rcu_periph_clock_enable(S600_UART##index##_tx_gpio_clk); \ gpio_init(S600_UART##index##_tx_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, S600_UART##index##_tx_pin); \ gpio_init(S600_UART##index##_rx_port, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, S600_UART##index##_rx_pin); \ usart_deinit(S600_UART##index##_com); \ usart_baudrate_set(S600_UART##index##_com, S600_UART##index##_baudrate); \ usart_word_length_set(S600_UART##index##_com, USART_WL_8BIT); \ usart_stop_bit_set(S600_UART##index##_com, USART_STB_1BIT); \ usart_parity_config(S600_UART##index##_com, USART_PM_NONE); \ usart_hardware_flow_rts_config(S600_UART##index##_com, USART_RTS_DISABLE); \ usart_hardware_flow_cts_config(S600_UART##index##_com, USART_CTS_DISABLE); \ usart_receive_config(S600_UART##index##_com, USART_RECEIVE_ENABLE); \ usart_transmit_config(S600_UART##index##_com, USART_TRANSMIT_ENABLE); \ } while (0) #define S600_UART_TX_IRQ_INIT(index) \ do { \ s600_uarts[index].tx_poll = s600_uart_irq_tx; \ nvic_irq_enable(S600_UART##index##_irq, 0, 0); \ } while (0) #define S600_UART_RX_IRQ_INIT(index) \ do { \ s600_uarts[index].rx_poll = s600_uart_irq_rx; \ usart_interrupt_enable(S600_UART##index##_com, USART_INT_RBNE); \ nvic_irq_enable(S600_UART##index##_irq, 0, 0); \ } while (0) #if S600_UART_USE_DMA #define S600_UART_TX_DMA_INIT(index) \ do { \ dma_parameter_struct dma_init_struct; \ s600_uarts[index].tx_poll = s600_uart_dma_tx; \ s600_uarts[index].tx_dma = S600_UART##index##_tx_dma; \ s600_uarts[index].tx_dma_ch = S600_UART##index##_tx_dma_ch; \ rcu_periph_clock_enable(S600_UART##index##_tx_dma_clk); \ dma_deinit(S600_UART##index##_tx_dma, S600_UART##index##_tx_dma_ch); \ dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; \ dma_init_struct.memory_addr = (u32) s600_uarts[index].tx_cache; \ dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; \ dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; \ dma_init_struct.number = 0; \ dma_init_struct.periph_addr = S600_UART_DMA_ADDR(index); \ dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; \ dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; \ dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; \ dma_init(S600_UART##index##_tx_dma, S600_UART##index##_tx_dma_ch, &dma_init_struct); \ dma_circulation_disable(S600_UART##index##_tx_dma, S600_UART##index##_tx_dma_ch); \ usart_dma_transmit_config(S600_UART##index##_com, USART_DENT_ENABLE); \ } while (0) #define S600_UART_RX_DMA_INIT(index) \ do { \ dma_parameter_struct dma_init_struct; \ s600_uarts[index].rx_poll = s600_uart_dma_rx; \ s600_uarts[index].rx_dma = S600_UART##index##_rx_dma; \ s600_uarts[index].rx_dma_ch = S600_UART##index##_rx_dma_ch; \ rcu_periph_clock_enable(S600_UART##index##_rx_dma_clk); \ dma_deinit(S600_UART##index##_rx_dma, S600_UART##index##_rx_dma_ch); \ dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; \ dma_init_struct.memory_addr = (u32) s600_uarts[index].rx_cache; \ dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; \ dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; \ dma_init_struct.number = s600_uarts[index].rx_cache_size; \ dma_init_struct.periph_addr = S600_UART_DMA_ADDR(index); \ dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; \ dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; \ dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; \ dma_init(S600_UART##index##_rx_dma, S600_UART##index##_rx_dma_ch, &dma_init_struct); \ dma_circulation_enable(S600_UART##index##_rx_dma, S600_UART##index##_rx_dma_ch); \ dma_channel_enable(S600_UART##index##_rx_dma, S600_UART##index##_rx_dma_ch); \ usart_dma_receive_config(S600_UART##index##_com, USART_DENR_ENABLE); \ } while (0) #else #define S600_UART_TX_DMA_INIT(index) \ S600_UART_TX_IRQ_INIT(index) #define S600_UART_RX_DMA_INIT(index) \ S600_UART_RX_IRQ_INIT(index) #endif #define S600_UART_INIT_DMA(index) \ do { \ S600_UART_DEVICE_INIT(index); \ S600_UART_TX_DMA_INIT(index); \ S600_UART_RX_DMA_INIT(index); \ } while (0) #define S600_UART_INIT_IRQ(index) \ do { \ S600_UART_DEVICE_INIT(index); \ S600_UART_TX_IRQ_INIT(index); \ S600_UART_RX_IRQ_INIT(index); \ } while (0) // ================================================================================ static u16 s600_print_pos; static u8 s600_print_buff[S600_UART_FRAME_SIZE]; static u16 s600_uart_index; static bool s600_uart_valid; static bool s600_uart_escape; static u8 s600_uart_frame[S600_UART_FRAME_SIZE]; static u8 s600_uart_cache[S600_UART_CACHE_SIZE]; s600_uart_device_t s600_uarts[S600_UART_COUNT]; s600_uart_device_t *s600_uart_passthrough; // ================================================================================ void s600_uart_dma_tx(s600_uart_device_t *uart) { u32 value = S600_UART_DMA_CHCTL_TX(uart); if (value & DMA_CHXCTL_CHEN) { if (SET != dma_flag_get(uart->tx_dma, uart->tx_dma_ch, DMA_FLAG_FTF)) { return; } byte_queue_skip(&uart->tx_queue, uart->tx_length); S600_UART_DMA_CHCTL_TX(uart) = value & (~DMA_CHXCTL_CHEN); } uart->tx_length = byte_queue_peek(&uart->tx_queue); if (uart->tx_length > 0) { S600_UART_DMA_CHCNT_TX(uart) = uart->tx_length; S600_UART_DMA_CHMADDR_TX(uart) = (u32) byte_queue_head(&uart->tx_queue); dma_flag_clear(uart->tx_dma, uart->tx_dma_ch, DMA_FLAG_FTF); S600_UART_DMA_CHCTL_TX(uart) = value | DMA_CHXCTL_CHEN; } } void s600_uart_cache_data(s600_uart_device_t *uart, u8 *buff, u16 length) { #if S600_UART_USE_CACHE while (length > 0) { u8 remain = sizeof(uart->cache) - uart->cache_len; uart->cache_times = S600_UART_CACHE_TIMES; if (length < remain) { memcpy(uart->cache + uart->cache_len, buff, length); uart->cache_len += length; break; } memcpy(uart->cache + uart->cache_len, buff, remain); uart->on_data_received(uart->cache, sizeof(uart->cache)); uart->cache_len = 0; length -= remain; buff += remain; } #else if (length > 0) { uart->on_data_received(buff, length); } #endif } void s600_uart_dma_rx(s600_uart_device_t *uart) { u16 index = uart->rx_index; uart->rx_index = uart->rx_cache_size - S600_UART_DMA_CHCNT_RX(uart); if (uart->rx_index < index) { uart->do_cache_data(uart, uart->rx_cache + index, uart->rx_cache_size - index); uart->do_cache_data(uart, uart->rx_cache, uart->rx_index); } else { uart->do_cache_data(uart, uart->rx_cache + index, uart->rx_index - index); } } void s600_uart_irq_tx(s600_uart_device_t *uart) { } void s600_uart_irq_rx(s600_uart_device_t *uart) { u8 buff[128]; u8 length; length = s600_uart_read(uart, buff, sizeof(buff)); uart->do_cache_data(uart, buff, length); } void s600_uart_rx(s600_uart_device_t *uart) { u32 com = uart->com; while (usart_flag_get(com, USART_FLAG_RBNE) == SET) { u8 value = usart_data_receive(com); byte_queue_write(&uart->rx_queue, &value, 1); } } void s600_uart_device_tx(s600_uart_device_t *uart) { u32 com = uart->com; if (usart_flag_get(com, USART_FLAG_TBE) == SET) { u8 value; if (byte_queue_read(&uart->tx_queue, &value, 1) > 0) { usart_data_transmit(com, value); } else { usart_interrupt_disable(com, USART_INT_TBE); } } } void s600_uart_write(s600_uart_device_t *uart, const u8 *buff, u16 size) { while (size > 0) { u16 length = byte_queue_write(&uart->tx_queue, buff, size); if (uart->tx_dma == 0) { usart_interrupt_enable(uart->com, USART_INT_TBE); } if (length == size) { break; } if (uart->tx_dma != 0) { s600_uart_dma_tx(uart); } buff += length; size -= length; } } u16 s600_uart_read(s600_uart_device_t *uart, u8 *buff, u16 size) { return byte_queue_read(&uart->rx_queue, buff, size); } void s600_uart_write_byte(s600_uart_device_t *uart, u8 value) { s600_uart_write(uart, &value, 1); } u16 s600_uart_write_available(s600_uart_device_t *uart) { return byte_queue_get_free(&uart->tx_queue); } bool s600_uart_write_full(s600_uart_device_t *uart, const u8 *buff, u16 size) { if (s600_uart_write_available(uart) < size) { return false; } s600_uart_write(uart, buff, size); return true; } void s600_uart_write_byte_esc(s600_uart_device_t *uart, u8 value) { switch (value) { case CH_START: s600_uart_write_byte(uart, CH_ESC); value = CH_ESC_START; break; case CH_END: s600_uart_write_byte(uart, CH_ESC); value = CH_ESC_END; break; case CH_ESC: s600_uart_write_byte(uart, CH_ESC); value = CH_ESC_ESC; break; } s600_uart_write_byte(uart, value); } void s600_uart_message_init(s600_uart_message_t *msg, const void *buff, u16 size) { msg->buff = (u8 *) buff; msg->size = size; } void s600_uart_write_messages(s600_uart_device_t *uart, const s600_uart_message_t *msgs, u8 count) { const s600_uart_message_t *msg_end; u16 crc = 0; #ifdef CONFIG_BOARD_M6_JIG s600_uart_write_byte(uart, 0xAA); #endif s600_uart_write_byte(uart, CH_START); for (msg_end = msgs + count; msgs < msg_end; msgs++) { const u8 *buff = msgs->buff; const u8 *buff_end = buff + msgs->size; while (buff < buff_end) { u8 value = *buff++; s600_uart_write_byte_esc(uart, value); crc = s600_crc_put_byte(crc, value); } } s600_uart_write_byte_esc(uart, crc); s600_uart_write_byte_esc(uart, crc >> 8); s600_uart_write_byte(uart, CH_END); } // ================================================================================ static void s600_uart_process_cmd_can(u8 *buff, u16 length) { s600_can_efid_t efid; if (length < 5) { return; } efid.value = s600_decode_u32(buff); if (efid.dest == 0x00 && efid.src == 0x45) { s600_can_process_frame(efid, buff + 4, length - 4); } else { u8 mailbox = s600_can_wait_mailbox(); if (mailbox != CAN_NOMAILBOX) { s600_can_send_frame(mailbox, efid.value, buff + 4, length - 4); } } } static int s600_uart_process_cmd_version(u8 *buff, u16 length) { length = sizeof(CONFIG_BOARD_NAME) - 1; memcpy(buff, CONFIG_BOARD_NAME, length); return length; } static int s600_uart_process_command(u16 command, u8 *buff, u16 length) { return -1; } static s600_uart_device_t *s600_uart_get_device(int uart) { if (uart < NELEM(s600_uarts)) { return s600_uarts + uart; } return NULL; } static void s600_uart_passthrough_master(u8 *buff, u16 size) { s600_uart_write(s600_uart_passthrough, buff, size); } static void s600_uart_passthrough_slave(u8 *buff, u16 size) { s600_uart_write(s600_uart_get_main(), buff, size); } static int s600_uart_process_uart_config(u8 *buff, u16 length) { s600_uart_device_t *uart; if (length < 2) { return -1; } uart = s600_uart_get_device(buff[0]); if (uart == NULL) { return -1; } if (length > 5) { u32 baudrate = s600_decode_u32(buff + 2); usart_baudrate_set(uart->com, baudrate); } if (buff[1]) { usart_enable(uart->com); if ((buff[1] & 0x02) != 0) { s600_uart_passthrough = uart; uart->on_data_received = s600_uart_passthrough_slave; s600_uart_get_main()->on_data_received = s600_uart_passthrough_master; } } else { usart_disable(uart->com); } return 0; } static u32 s600_uart_gpio_decode_port(u8 value) { u8 index = value >> 5; rcu_periph_clock_enable(s600_gpio_rcu_map[index]); return s600_gpio_map[index]; } static u32 s600_uart_gpio_decode_pin(u8 value) { return 1 << (value & 0x1F); } static u32 s600_uart_exti_decode_port(u8 value) { return value >> 5; } static u32 s600_uart_exti_decode_pin(u8 value) { return value & 0x1F; } static int s600_uart_process_gpio_init(u8 *buff, u16 length) { if (length < 6) { u32 port = s600_uart_gpio_decode_port(buff[0]); u32 pin = s600_uart_gpio_decode_pin(buff[0]); gpio_init(port, buff[1], buff[2], pin); } else { gpio_pin_remap_config(s600_decode_u32(buff + 1), (ControlStatus) buff[5]); } return 1; } static int s600_uart_process_gpio_input_bit_get(u8 *buff, u16 length) { u32 port = s600_uart_gpio_decode_port(buff[0]); u32 pin = s600_uart_gpio_decode_pin(buff[0]); if (length > 1) { gpio_init(port, buff[1], GPIO_OSPEED_50MHZ, pin); } buff[1] = gpio_input_bit_get(port, pin); return 2; } static int s600_uart_process_gpio_output_bit_set(u8 *buff, u16 length) { u32 port = s600_uart_gpio_decode_port(buff[0]); u32 pin = s600_uart_gpio_decode_pin(buff[0]); if (length > 2) { gpio_init(port, buff[2], GPIO_OSPEED_50MHZ, pin); } if (buff[1] == 0) { gpio_bit_reset(port, pin); } else { gpio_bit_set(port, pin); } return 1; } static int s600_uart_process_gpio_output_bit_get(u8 *buff, u16 length) { u32 port = s600_uart_gpio_decode_port(buff[0]); u32 pin = s600_uart_gpio_decode_pin(buff[0]); buff[1] = gpio_output_bit_get(port, pin); return 2; } static int s600_uart_process_gpio_input_port_get(u8 *buff, u16 length) { u32 port = s600_uart_gpio_decode_port(buff[0]); s600_encode_u16(buff + 1, gpio_input_port_get(port)); return 3; } static int s600_uart_process_gpio_output_port_set(u8 *buff, u16 length) { u32 port = s600_uart_gpio_decode_port(buff[0]); gpio_port_write(port, s600_decode_u16(buff + 1)); return 1; } static int s600_uart_process_gpio_output_port_get(u8 *buff, u16 length) { u32 port = s600_uart_gpio_decode_port(buff[0]); s600_encode_u16(buff + 1, gpio_output_port_get(port)); return 3; } static int s600_uart_process_adc(u8 *buff, u16 length) { return s600_adc_get_values(buff[0], buff + 1) - buff + 1; } static int s600_uart_process_write_dac(int index, u8 *buff, u16 length) { length = s600_dac_write(index, buff, length); s600_encode_u16(buff, length); return 2; } static int s600_uart_process_dac_set_enable(u8 *buff, u16 length) { u8 dac = buff[0]; if (buff[1] == 0) { s600_dac_disable(dac); } else { s600_dac_enable(dac); } return 1; } static int s600_uart_process_dac_set_volume(u8 *buff, u16 length) { s600_dac_set_volume(buff[0], buff[1]); return 1; } static int s600_uart_process_dac_set_rate(u8 *buff, u16 length) { s600_dac_set_rate(buff[0], s600_decode_u16(buff + 1)); return 1; } static int s600_uart_process_single_comm_config(u8 *buff, u16 length) { if (length < 2) { return -1; } if (buff[1]) { u32 port, pin; if (length < 3) { return -1; } port = s600_uart_exti_decode_port(buff[2]); pin = s600_uart_exti_decode_pin(buff[2]); s600_turn_key_init(buff[0], port, pin); } else { s600_turn_key_deinit(buff[0]); } return 0; } static int s600_uart_process_spi_led_init(void) { ws2818_spi_init(); return 0; } static int s600_uart_process_spi_led_commit(void) { ws2818_commit(); return 0; } static int s600_uart_process_spi_led_clear(u8 *buff, u16 length) { u32 color; u8 index; u8 count; if (length > 0) { index = buff[0]; } else { index = 0; } if (length > 1) { count = buff[1]; } else { count = WS2818_LED_COUNT - index; } if (length < 5) { color = 0x00000000; } else { color = s600_decode_u24(buff + 2); } ws2818_set_color_burst(index, index + count, color); return 0; } static int s600_uart_process_spi_led_set_color(u8 *buff, u16 length) { u8 index; if (length < 1) { return -1; } for (index = buff[0], buff++, length--; length >= 3; index++) { ws2818_set_color(index, s600_decode_u24(buff)); length -= 3; buff += 3; } return 0; } static int s600_uart_process_reg_rw(u8 *buff, u16 length) { return 0; } static int s600_uart_process_mem_rw(u8 *buff, u16 length) { return 0; } static void s600_uart_exti_notify(u8 index) { exti_interrupt_flag_clear((exti_line_enum) BIT(index)); s600_uart_send_command(CMD_EXTI_NOTIFY, &index, 1); } static void s600_uart_put(struct s600_uart_device *uart, u8 *buff, u16 length) { const u8 *buff_end; for (buff_end = buff + length; buff < buff_end; buff++) { u8 value = *buff; switch (value) { case CH_START: s600_uart_index = 0; s600_uart_valid = true; s600_uart_escape = false; break; case CH_END: if (s600_uart_valid && s600_uart_index > 0) { s600_uart_process_frame(s600_uart_frame, s600_uart_index); s600_uart_index = 0; } s600_uart_valid = false; s600_uart_escape = false; break; case CH_ESC: s600_uart_escape = true; break; default: if (s600_uart_escape) { s600_uart_escape = false; switch (value) { case CH_ESC_START: value = CH_START; break; case CH_ESC_END: value = CH_END; break; case CH_ESC_ESC: value = CH_ESC; break; default: s600_uart_valid = false; break; } } if (s600_uart_index < sizeof(s600_uart_frame)) { s600_uart_frame[s600_uart_index++] = value; } else { s600_uart_valid = false; } } } } void s600_uart_poll(void) { int i; for (i = 0; i < NELEM(s600_uarts); i++) { s600_uart_device_t *uart = s600_uarts + i; uart->tx_poll(uart); uart->rx_poll(uart); #if S600_UART_USE_CACHE if (uart->cache_times > 0) { if (uart->cache_times == 1 && uart->cache_len > 0) { uart->on_data_received(uart->cache, uart->cache_len); uart->cache_len = 0; } uart->cache_times--; } #endif } } void s600_uart_print_flush(short_command_t cmd) { s600_uart_send_command(cmd, s600_print_buff, s600_print_pos); s600_print_pos = 0; } void s600_uart0_received(u8 *buff, u16 length) { s600_uart_send_command(CMD_UART0, buff, length); } void s600_uart1_received(u8 *buff, u16 length) { s600_uart_send_command(CMD_UART1, buff, length); } void s600_uart2_received(u8 *buff, u16 length) { s600_uart_send_command(CMD_UART2, buff, length); } void s600_uart3_received(u8 *buff, u16 length) { s600_uart_send_command(CMD_UART3, buff, length); } void s600_uart4_received(u8 *buff, u16 length) { s600_uart_send_command(CMD_UART4, buff, length); } void s600_uart_rcu_config(void) { u16 position = 0; int i; for (i = 0; i < NELEM(s600_uarts); i++) { s600_uart_device_t *uart = s600_uarts + i; if (i == CONFIG_UART_MAIN) { uart->tx_cache_size = S600_UART_MAIN_TX_MEM_SIZE; uart->rx_cache_size = S600_UART_MAIN_RX_MEM_SIZE; uart->do_cache_data = s600_uart_put; } else { uart->tx_cache_size = S600_UART_TX_MEM_SIZE; uart->rx_cache_size = S600_UART_RX_MEM_SIZE; uart->do_cache_data = s600_uart_cache_data; } uart->tx_cache = s600_uart_cache + position; uart->rx_cache = uart->tx_cache + uart->tx_cache_size; } S600_UART_INIT_DMA(0); S600_UART_INIT_DMA(1); #ifdef CONFIG_BOARD_M6_CDL S600_UART_INIT_IRQ(2); #else S600_UART_INIT_DMA(2); #endif S600_UART_INIT_DMA(3); S600_UART_INIT_IRQ(4); usart_enable(s600_uart_get_main()->com); } int fputc(int ch, FILE *f) { if (ch == '\n') { if (s600_print_pos > 0) { s600_uart_print_flush(CMD_PRINT_END); } } else { while (1) { if (s600_print_pos < sizeof(s600_print_buff)) { s600_print_buff[s600_print_pos] = ch; s600_print_pos++; break; } s600_uart_print_flush(CMD_PRINT_ADD); } } return ch; } void USART0_IRQHandler(void) { s600_uart_rx(s600_uarts); s600_uart_device_tx(s600_uarts); } void USART1_IRQHandler(void) { s600_uart_rx(s600_uarts + 1); s600_uart_device_tx(s600_uarts + 1); } void USART2_IRQHandler(void) { s600_uart_rx(s600_uarts + 2); s600_uart_device_tx(s600_uarts + 2); } void UART3_IRQHandler(void) { s600_uart_rx(s600_uarts + 3); s600_uart_device_tx(s600_uarts + 3); } void UART4_IRQHandler(void) { s600_uart_rx(s600_uarts + 4); s600_uart_device_tx(s600_uarts + 4); }