#ifndef __SERIAL_H__ #define __SERIAL_H__ #include #include struct dma_tx_buf { /* The following fields are accessed only from DMA ISR */ ssize_t xfr_start; /* Start index of running DMA transfer */ ssize_t xfr_end; /* End index of running DMA transfer plus one */ bool wraparound; ssize_t xfr_next; bool ack; /* The following fields are written only from non-interrupt code */ ssize_t wr_pos; /* Next index to be written */ ssize_t wr_idx; ssize_t packet_end[8]; /* The following may be accessed by anything */ uint8_t data[256]; }; struct uart_dma_state { struct dma_tx_buf tx_buf; uint32_t retransmissions, packet_count; ErrorCode error; uint64_t last_error; uint64_t last_packet; uint64_t last_transmission; struct cobs_decode_state cobs_state; DMA_Channel_TypeDef *tx_dma_ch; USART_TypeDef *usart; uint8_t rx_buf[256]; uint8_t addr; }; struct __attribute__((__packed__)) ll_pkt { uint32_t crc32; /* CRC computed over entire packet starting here */ uint8_t src; uint8_t dst; uint8_t pid; uint8_t type; uint8_t data[0]; }; #define SER_ADDR_BROADCAST 0xff extern volatile struct uart_dma_state uart_st; void uart_dma_init(USART_TypeDef *usart, DMA_Channel_TypeDef *tx_dma_ch, int addr); int uart_send_packet_nonblocking(struct ll_pkt *pkt, size_t pkt_len); int uart_ack_packet(uint8_t idx); void uart_dma_interrupt(DMA_Channel_TypeDef *ch, uint32_t flags); void uart_interrupt(uint32_t isr); extern void uart_handle_user_packet(struct ll_pkt *pkt, size_t len); #endif // __SERIAL_H__