|
|
@@ -0,0 +1,977 @@
|
|
|
+#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);
|
|
|
+}
|
|
|
+
|