aboutsummaryrefslogtreecommitdiff
path: root/fdl/ch573/uart.fdl
blob: 9a4f0c554edeaa94d0818ffc0d935d6a78763839 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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;
};