1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 #include <stdint.h>
22 
23 /* ---------------------------- Register Layout ------------------------------ */
24 
25 /* The TWAI peripheral's registers are 8bits, however the ESP32 can only access
26  * peripheral registers every 32bits. Therefore each TWAI register is mapped to
27  * the least significant byte of every 32bits.
28  */
29 
30 typedef volatile struct twai_dev_s {
31     //Configuration and Control Registers
32     union {
33         struct {
34             uint32_t rm: 1;                     /* MOD.0 Reset Mode */
35             uint32_t lom: 1;                    /* MOD.1 Listen Only Mode */
36             uint32_t stm: 1;                    /* MOD.2 Self Test Mode */
37             uint32_t afm: 1;                    /* MOD.3 Acceptance Filter Mode */
38             uint32_t reserved4: 28;             /* Internal Reserved. MOD.4 Sleep Mode not supported */
39         };
40         uint32_t val;
41     } mode_reg;                                 /* Address 0x0000 */
42     union {
43         struct {
44             uint32_t tr: 1;                     /* CMR.0 Transmission Request */
45             uint32_t at: 1;                     /* CMR.1 Abort Transmission */
46             uint32_t rrb: 1;                    /* CMR.2 Release Receive Buffer */
47             uint32_t cdo: 1;                    /* CMR.3 Clear Data Overrun */
48             uint32_t srr: 1;                    /* CMR.4 Self Reception Request */
49             uint32_t reserved5: 27;             /* Internal Reserved */
50         };
51         uint32_t val;
52     } command_reg;                              /* Address 0x0004 */
53     union {
54         struct {
55             uint32_t rbs: 1;                    /* SR.0 Receive Buffer Status */
56             uint32_t dos: 1;                    /* SR.1 Data Overrun Status */
57             uint32_t tbs: 1;                    /* SR.2 Transmit Buffer Status */
58             uint32_t tcs: 1;                    /* SR.3 Transmission Complete Status */
59             uint32_t rs: 1;                     /* SR.4 Receive Status */
60             uint32_t ts: 1;                     /* SR.5 Transmit Status */
61             uint32_t es: 1;                     /* SR.6 Error Status */
62             uint32_t bs: 1;                     /* SR.7 Bus Status */
63             uint32_t reserved8: 24;             /* Internal Reserved */
64         };
65         uint32_t val;
66     } status_reg;                               /* Address 0x0008 */
67     union {
68         struct {
69             uint32_t ri: 1;                     /* IR.0 Receive Interrupt */
70             uint32_t ti: 1;                     /* IR.1 Transmit Interrupt */
71             uint32_t ei: 1;                     /* IR.2 Error Interrupt */
72             uint32_t doi: 1;                    /* IR.3 Data Overrun Interrupt */
73             uint32_t reserved4: 1;              /* Internal Reserved (Wake-up not supported) */
74             uint32_t epi: 1;                    /* IR.5 Error Passive Interrupt */
75             uint32_t ali: 1;                    /* IR.6 Arbitration Lost Interrupt */
76             uint32_t bei: 1;                    /* IR.7 Bus Error Interrupt */
77             uint32_t reserved8: 24;             /* Internal Reserved */
78         };
79         uint32_t val;
80     } interrupt_reg;                           /* Address 0x000C */
81     union {
82         struct {
83             uint32_t rie: 1;                    /* IER.0 Receive Interrupt Enable */
84             uint32_t tie: 1;                    /* IER.1 Transmit Interrupt Enable */
85             uint32_t eie: 1;                    /* IER.2 Error Interrupt Enable */
86             uint32_t doie: 1;                   /* IER.3 Data Overrun Interrupt Enable */
87             uint32_t brp_div: 1;                /* THIS IS NOT AN INTERRUPT. brp_div will prescale BRP by 2. Only available on ESP32 Revision 2 or later. Reserved otherwise */
88             uint32_t epie: 1;                   /* IER.5 Error Passive Interrupt Enable */
89             uint32_t alie: 1;                   /* IER.6 Arbitration Lost Interrupt Enable */
90             uint32_t beie: 1;                   /* IER.7 Bus Error Interrupt Enable */
91             uint32_t reserved8: 24;             /* Internal Reserved */
92         };
93         uint32_t val;
94     } interrupt_enable_reg;                     /* Address 0x0010 */
95     uint32_t reserved_14;
96     union {
97         struct {
98             uint32_t brp: 6;                    /* BTR0[5:0] Baud Rate Prescaler */
99             uint32_t sjw: 2;                    /* BTR0[7:6] Synchronization Jump Width*/
100             uint32_t reserved8: 24;             /* Internal Reserved */
101         };
102         uint32_t val;
103     } bus_timing_0_reg;                         /* Address 0x0018 */
104     union {
105         struct {
106             uint32_t tseg1: 4;                  /* BTR1[3:0] Timing Segment 1 */
107             uint32_t tseg2: 3;                  /* BTR1[6:4] Timing Segment 2 */
108             uint32_t sam: 1;                    /* BTR1.7 Sampling*/
109             uint32_t reserved8: 24;             /* Internal Reserved */
110         };
111         uint32_t val;
112     } bus_timing_1_reg;                         /* Address 0x001C */
113     uint32_t reserved_20;                       /* Address 0x0020 (Output control not supported) */
114     uint32_t reserved_24;                       /* Address 0x0024 (Test Register not supported) */
115     uint32_t reserved_28;                       /* Address 0x0028 */
116 
117     //Capture and Counter Registers
118     union {
119         struct {
120             uint32_t alc: 5;                    /* ALC[4:0] Arbitration lost capture */
121             uint32_t reserved5: 27;             /* Internal Reserved */
122         };
123         uint32_t val;
124     } arbitration_lost_captue_reg;              /* Address 0x002C */
125     union {
126         struct {
127             uint32_t seg: 5;                    /* ECC[4:0] Error Code Segment 0 to 5 */
128             uint32_t dir: 1;                    /* ECC.5 Error Direction (TX/RX) */
129             uint32_t errc: 2;                   /* ECC[7:6] Error Code */
130             uint32_t reserved8: 24;             /* Internal Reserved */
131         };
132         uint32_t val;
133     } error_code_capture_reg;                   /* Address 0x0030 */
134     union {
135         struct {
136             uint32_t ewl: 8;                    /* EWL[7:0] Error Warning Limit */
137             uint32_t reserved8: 24;             /* Internal Reserved */
138         };
139         uint32_t val;
140     } error_warning_limit_reg;                  /* Address 0x0034 */
141     union {
142         struct {
143             uint32_t rxerr: 8;                  /* RXERR[7:0] Receive Error Counter */
144             uint32_t reserved8: 24;             /* Internal Reserved */
145         };
146         uint32_t val;
147     } rx_error_counter_reg;                     /* Address 0x0038 */
148     union {
149         struct {
150             uint32_t txerr: 8;                  /* TXERR[7:0] Receive Error Counter */
151             uint32_t reserved8: 24;             /* Internal Reserved */
152         };
153         uint32_t val;
154     } tx_error_counter_reg;                     /* Address 0x003C */
155 
156     //Shared Registers (TX Buff/RX Buff/Acc Filter)
157     union {
158         struct {
159             union {
160                 struct {
161                     uint32_t byte: 8;           /* ACRx[7:0] Acceptance Code */
162                     uint32_t reserved8: 24;     /* Internal Reserved */
163                 };
164                 uint32_t val;
165             } acr[4];
166             union {
167                 struct {
168                     uint32_t byte: 8;           /* AMRx[7:0] Acceptance Mask */
169                     uint32_t reserved8: 24;     /* Internal Reserved */
170                 };
171                 uint32_t val;
172             } amr[4];
173             uint32_t reserved_60;
174             uint32_t reserved_64;
175             uint32_t reserved_68;
176             uint32_t reserved_6c;
177             uint32_t reserved_70;
178         } acceptance_filter;
179         union {
180             struct {
181                 uint32_t byte: 8;               /* TX/RX Byte X [7:0] */
182                 uint32_t reserved24: 24;        /* Internal Reserved */
183             };
184             uint32_t val;
185         } tx_rx_buffer[13];
186     };                                          /* Address 0x0040 - 0x0070 */
187 
188     //Misc Registers
189     union {
190         struct {
191             uint32_t rmc: 7;                    /* RMC[6:0] RX Message Counter */
192             uint32_t reserved7: 25;             /* Internal Reserved */
193         };
194         uint32_t val;
195     } rx_message_counter_reg;                   /* Address 0x0074 */
196     uint32_t reserved_78;                       /* Address 0x0078 (RX Buffer Start Address not supported) */
197     union {
198         struct {
199             uint32_t cd: 3;                     /* CDR[2:0] CLKOUT frequency selector based of fOSC */
200             uint32_t co: 1;                     /* CDR.3 CLKOUT enable/disable */
201             uint32_t reserved4: 3;              /* Internal Reserved. RXINTEN and CBP not supported */
202             uint32_t cm: 1;                     /* CDR.7 Register Layout. Basic:0 Extended:1 */
203             uint32_t reserved6: 24;             /* Internal Reserved  */
204         };
205         uint32_t val;
206     } clock_divider_reg;                        /* Address 0x007C */
207 } twai_dev_t;
208 
209 _Static_assert(sizeof(twai_dev_t) == 128, "TWAI registers should be 32 * 4 bytes");
210 
211 extern twai_dev_t TWAI;
212 
213 #ifdef __cplusplus
214 }
215 #endif
216