import "ch573/common.fdl"; /** Package for the UART subsystem. */ package ch573.uart { location uart0_base = 0x4000_3000; location uart1_base = 0x4000_3400; location uart2_base = 0x4000_3800; location uart3_base = 0x4000_3C00; using ch573.common; type uart_t : struct { /** MODEM Control Register */ reg mcr(8) : struct { /** DTR signal output level control (UART0 only) */ dtr : bit_t; /** RTS signal output level control (UART0 only) */ rts : bit_t; /** User-defined MODEM control bit (UART0 only) */ out1 : bit_t; union { /** UART interrupt request output control */ out2 : bit_t; int_oe : bit_t; }; /** Internal loop-back test mode (UART0 only) */ loop : bit_t; /** Automatic CTS and RTS hardware flow control (UART0 only) */ au_flow : bit_t; /** DTR pin output is in transmission (UART0 only) */ tnow : bit_t; /** Half-duplex mode control (UART0 only) */ half : bit_t; }; /** Interrupt Enable Register */ reg ier(8) : struct { /** Receive data interrupt enable */ recv_rdy : bit_t; /** Transmit hold register empty interrupt enable */ thr_empty : bit_t; /** Receive line status interrupt enable */ line_stat : bit_t; /** Modem status change interrupt enable (UART0 only) */ modem_chg : bit_t; /** DTR output enable (UART0 only) */ dtr_en : bit_t; /** RTS output enable (UART0 only) */ rts_en : bit_t; /** TXD output enable */ txd_en : bit_t; /** Software reset control */ reset : bit_t; }; /** FIFO Control Register */ reg fcr(8) : struct { /** FIFO enable */ fifo_en : bit_t; /** Clear receiver FIFO */ rx_fifo_clr : bit_t; /** Clear transmitter FIFO */ tx_fifo_clr : bit_t; reserved(3); /** FIFO trigger level select */ fifo_trig : (2); }; /** Line Control Register */ reg lcr(8) : struct { /** UART word size (5-8 bits) */ word_sz : enum(2) { [[ c: unqualified ]] WORD_SZ_5_BITS = 0b00, [[ c: unqualified ]] WORD_SZ_6_BITS = 0b01, [[ c: unqualified ]] WORD_SZ_7_BITS = 0b10, [[ c: unqualified ]] WORD_SZ_8_BITS = 0b11, }; /** Stop bit setting */ stop_bit : bit_t; /** Parity bit enable */ par_en : bit_t; /** Parity bit format */ par_mod : (2); /** Generate break line interval */ break_en : bit_t; /** Divisor latch access enable */ dlab : bit_t; }; /** Interrupt Identification Register */ reg iir(8) : struct { union { /** No interrupt status */ struct { no_int : bit_t; reserved(3); }; /** Interrupt flag mask */ int_mask : (4); }; reserved(2); /** FIFO enable status */ fifo_id : (2); }; /** Line Status Register */ reg lsr(8) : struct { /** Data ready */ data_rdy : bit_t; /** Overrun error */ over_err : bit_t; /** Parity error */ par_err : bit_t; /** Framing error */ frame_err : bit_t; /** Break interrupt */ break_int : bit_t; /** Transmitter holding register empty */ thr_empty : bit_t; /** Transmitter empty */ tx_empty : bit_t; /** FIFO data error */ fifo_err : bit_t; }; skip_to(0x08); union { /** Transmit Hold Register. */ reg thr(8); /** Receive Buffer Register. */ reg rbr(8); }; reserved(8); assert_pos(0x0A); /** Receive FIFO Count Register */ reg rfc(8); assert_pos(0x0B); /** Transmit FIFO Count Register */ reg tfc(8); assert_pos(0x0C); /** Baud Rate Divisor Latch */ reg dl(16); assert_pos(0x0E); /** Prescaler Divisor Register */ reg div(8); assert_pos(0x0F); /** Slave Address Register (UART0 only) */ reg adr(8); }; instance uart0 at uart0_base : uart_t; instance uart1 at uart1_base : uart_t; instance uart2 at uart2_base : uart_t; instance uart3 at uart3_base : uart_t; };