1use core::cell::Cell;
6use core::num::NonZeroUsize;
7use kernel::errorcode::ErrorCode;
8use kernel::hil::uart::{self, Configure, Receive, ReceiveClient, Transmit, TransmitClient};
9use kernel::utilities::StaticRef;
10use kernel::utilities::{
11 cells::{OptionalCell, TakeCell},
12 registers::{
13 interfaces::{ReadWriteable, Readable, Writeable},
14 register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly,
15 },
16};
17
18register_structs! {
19 Scb5Registers {
20 (0x000 => ctrl: ReadWrite<u32, CTRL::Register>),
21 (0x004 => status: ReadOnly<u32>),
22 (0x008 => cmd_resp_ctrl: ReadWrite<u32, CMD_RESP_CTRL::Register>),
23 (0x00C => cmd_resp_status: ReadOnly<u32, CMD_RESP_STATUS::Register>),
24 (0x010 => _reserved0),
25 (0x020 => spi_ctrl: ReadWrite<u32, SPI_CTRL::Register>),
26 (0x024 => spi_status: ReadOnly<u32, SPI_STATUS::Register>),
27 (0x028 => _reserved1),
28 (0x040 => uart_ctrl: ReadWrite<u32, UART_CTRL::Register>),
29 (0x044 => uart_tx_ctrl: ReadWrite<u32, UART_TX_CTRL::Register>),
30 (0x048 => uart_rx_ctrl: ReadWrite<u32, UART_RX_CTRL::Register>),
31 (0x04C => uart_rx_status: ReadOnly<u32>),
32 (0x050 => uart_flow_ctrl: ReadWrite<u32, UART_FLOW_CTRL::Register>),
33 (0x054 => _reserved2),
34 (0x060 => i2c_ctrl: ReadWrite<u32, I2C_CTRL::Register>),
35 (0x064 => i2c_status: ReadOnly<u32, I2C_STATUS::Register>),
36 (0x068 => i2c_m_cmd: ReadWrite<u32, I2C_M_CMD::Register>),
37 (0x06C => i2c_s_cmd: ReadWrite<u32, I2C_S_CMD::Register>),
38 (0x070 => i2c_cfg: ReadWrite<u32, I2C_CFG::Register>),
39 (0x074 => _reserved3),
40 (0x200 => tx_ctrl: ReadWrite<u32, TX_CTRL::Register>),
41 (0x204 => tx_fifo_ctrl: ReadWrite<u32, TX_FIFO_CTRL::Register>),
42 (0x208 => tx_fifo_status: ReadOnly<u32, TX_FIFO_STATUS::Register>),
43 (0x20C => _reserved4),
44 (0x240 => tx_fifo_wr: WriteOnly<u32, TX_FIFO_WR::Register>),
45 (0x244 => _reserved5),
46 (0x300 => rx_ctrl: ReadWrite<u32, RX_CTRL::Register>),
47 (0x304 => rx_fifo_ctrl: ReadWrite<u32, RX_FIFO_CTRL::Register>),
48 (0x308 => rx_fifo_status: ReadOnly<u32, RX_FIFO_STATUS::Register>),
49 (0x30C => _reserved6),
50 (0x310 => rx_match: ReadWrite<u32, RX_MATCH::Register>),
51 (0x314 => _reserved7),
52 (0x340 => rx_fifo_rd: ReadOnly<u32, RX_FIFO_RD::Register>),
53 (0x344 => rx_fifo_rd_silent: ReadOnly<u32>),
54 (0x348 => _reserved8),
55 (0xE00 => intr_cause: ReadOnly<u32, INTR_CAUSE::Register>),
56 (0xE04 => _reserved9),
57 (0xE80 => intr_i2c_ec: ReadWrite<u32, INTR_I2C_EC::Register>),
58 (0xE84 => _reserved10),
59 (0xE88 => intr_i2c_ec_mask: ReadWrite<u32, INTR_I2C_EC_MASK::Register>),
60 (0xE8C => intr_i2c_ec_masked: ReadOnly<u32, INTR_I2C_EC_MASKED::Register>),
61 (0xE90 => _reserved11),
62 (0xEC0 => intr_spi_ec: ReadWrite<u32, INTR_SPI_EC::Register>),
63 (0xEC4 => _reserved12),
64 (0xEC8 => intr_spi_ec_mask: ReadWrite<u32, INTR_SPI_EC_MASK::Register>),
65 (0xECC => intr_spi_ec_masked: ReadOnly<u32, INTR_SPI_EC_MASKED::Register>),
66 (0xED0 => _reserved13),
67 (0xF00 => intr_m: ReadWrite<u32, INTR_M::Register>),
68 (0xF04 => intr_m_set: ReadWrite<u32, INTR_M_SET::Register>),
69 (0xF08 => intr_m_mask: ReadWrite<u32, INTR_M_MASK::Register>),
70 (0xF0C => intr_m_masked: ReadOnly<u32, INTR_M_MASKED::Register>),
71 (0xF10 => _reserved14),
72 (0xF40 => intr_s: ReadWrite<u32, INTR_S::Register>),
73 (0xF44 => intr_s_set: ReadWrite<u32, INTR_S_SET::Register>),
74 (0xF48 => intr_s_mask: ReadWrite<u32, INTR_S_MASK::Register>),
75 (0xF4C => intr_s_masked: ReadOnly<u32, INTR_S_MASKED::Register>),
76 (0xF50 => _reserved15),
77 (0xF80 => intr_tx: ReadWrite<u32, INTR_TX::Register>),
78 (0xF84 => intr_tx_set: ReadWrite<u32, INTR_TX_SET::Register>),
79 (0xF88 => intr_tx_mask: ReadWrite<u32, INTR_TX_MASK::Register>),
80 (0xF8C => intr_tx_masked: ReadOnly<u32, INTR_TX_MASKED::Register>),
81 (0xF90 => _reserved16),
82 (0xFC0 => intr_rx: ReadWrite<u32, INTR_RX::Register>),
83 (0xFC4 => intr_rx_set: ReadWrite<u32, INTR_RX_SET::Register>),
84 (0xFC8 => intr_rx_mask: ReadWrite<u32, INTR_RX_MASK::Register>),
85 (0xFCC => intr_rx_masked: ReadOnly<u32, INTR_RX_MASKED::Register>),
86 (0xFD0 => @END),
87 }
88}
89register_bitfields![u32,
90CTRL [
91 OVS OFFSET(0) NUMBITS(4) [],
92 EC_AM_MODE OFFSET(8) NUMBITS(1) [],
93 EC_OP_MODE OFFSET(9) NUMBITS(1) [],
94 EZ_MODE OFFSET(10) NUMBITS(1) [],
95 BYTE_MODE OFFSET(11) NUMBITS(1) [],
96 CMD_RESP_MODE OFFSET(12) NUMBITS(1) [],
97 ADDR_ACCEPT OFFSET(16) NUMBITS(1) [],
98 BLOCK OFFSET(17) NUMBITS(1) [],
99 MODE OFFSET(24) NUMBITS(2) [
100 InterIntegratedCircuitsI2CMode = 0,
101 SerialPeripheralInterfaceSPIMode = 1,
102 UniversalAsynchronousReceiverTransmitterUARTMode = 2
103 ],
104 ENABLED OFFSET(31) NUMBITS(1) []
105],
106STATUS [
107 EC_BUSY OFFSET(0) NUMBITS(1) []
108],
109CMD_RESP_CTRL [
110 BASE_RD_ADDR OFFSET(0) NUMBITS(9) [],
111 BASE_WR_ADDR OFFSET(16) NUMBITS(9) []
112],
113CMD_RESP_STATUS [
114 CURR_RD_ADDR OFFSET(0) NUMBITS(9) [],
115 CURR_WR_ADDR OFFSET(16) NUMBITS(9) [],
116 CMD_RESP_EC_BUS_BUSY OFFSET(30) NUMBITS(1) [],
117 CMD_RESP_EC_BUSY OFFSET(31) NUMBITS(1) []
118],
119SPI_CTRL [
120 SSEL_CONTINUOUS OFFSET(0) NUMBITS(1) [],
121 SELECT_PRECEDE OFFSET(1) NUMBITS(1) [],
122 CPHA OFFSET(2) NUMBITS(1) [],
123 CPOL OFFSET(3) NUMBITS(1) [],
124 LATE_MISO_SAMPLE OFFSET(4) NUMBITS(1) [],
125 SCLK_CONTINUOUS OFFSET(5) NUMBITS(1) [],
126 SSEL_POLARITY0 OFFSET(8) NUMBITS(1) [],
127 SSEL_POLARITY1 OFFSET(9) NUMBITS(1) [],
128 SSEL_POLARITY2 OFFSET(10) NUMBITS(1) [],
129 SSEL_POLARITY3 OFFSET(11) NUMBITS(1) [],
130 LOOPBACK OFFSET(16) NUMBITS(1) [],
131 MODE OFFSET(24) NUMBITS(2) [
132 SPI_MOTOROLA = 0,
133 SPI_TI = 1,
134 SPI_NS = 2
135 ],
136 SSEL OFFSET(26) NUMBITS(2) [],
137 MASTER_MODE OFFSET(31) NUMBITS(1) []
138],
139SPI_STATUS [
140 BUS_BUSY OFFSET(0) NUMBITS(1) [],
141 SPI_EC_BUSY OFFSET(1) NUMBITS(1) [],
142 CURR_EZ_ADDR OFFSET(8) NUMBITS(8) [],
143 BASE_EZ_ADDR OFFSET(16) NUMBITS(8) []
144],
145UART_CTRL [
146 LOOPBACK OFFSET(16) NUMBITS(1) [],
147 MODE OFFSET(24) NUMBITS(2) [
148 StandardUARTSubmode = 0,
149 UART_SMARTCARD = 1,
150 InfraredDataAssociationIrDASubmodeReturnToZeroModulationScheme = 2
151 ]
152],
153UART_TX_CTRL [
154 STOP_BITS OFFSET(0) NUMBITS(3) [],
155 PARITY OFFSET(4) NUMBITS(1) [],
156 PARITY_ENABLED OFFSET(5) NUMBITS(1) [],
157 RETRY_ON_NACK OFFSET(8) NUMBITS(1) []
158],
159UART_RX_CTRL [
160 STOP_BITS OFFSET(0) NUMBITS(3) [],
161 PARITY OFFSET(4) NUMBITS(1) [],
162 PARITY_ENABLED OFFSET(5) NUMBITS(1) [],
163 POLARITY OFFSET(6) NUMBITS(1) [],
164 DROP_ON_PARITY_ERROR OFFSET(8) NUMBITS(1) [],
165 DROP_ON_FRAME_ERROR OFFSET(9) NUMBITS(1) [],
166 MP_MODE OFFSET(10) NUMBITS(1) [],
167 LIN_MODE OFFSET(12) NUMBITS(1) [],
168 SKIP_START OFFSET(13) NUMBITS(1) [],
169 BREAK_WIDTH OFFSET(16) NUMBITS(4) []
170],
171UART_RX_STATUS [
172 BR_COUNTER OFFSET(0) NUMBITS(12) []
173],
174UART_FLOW_CTRL [
175 TRIGGER_LEVEL OFFSET(0) NUMBITS(8) [],
176 RTS_POLARITY OFFSET(16) NUMBITS(1) [],
177 CTS_POLARITY OFFSET(24) NUMBITS(1) [],
178 CTS_ENABLED OFFSET(25) NUMBITS(1) []
179],
180I2C_CTRL [
181 HIGH_PHASE_OVS OFFSET(0) NUMBITS(4) [],
182 LOW_PHASE_OVS OFFSET(4) NUMBITS(4) [],
183 M_READY_DATA_ACK OFFSET(8) NUMBITS(1) [],
184 M_NOT_READY_DATA_NACK OFFSET(9) NUMBITS(1) [],
185 S_GENERAL_IGNORE OFFSET(11) NUMBITS(1) [],
186 S_READY_ADDR_ACK OFFSET(12) NUMBITS(1) [],
187 S_READY_DATA_ACK OFFSET(13) NUMBITS(1) [],
188 S_NOT_READY_ADDR_NACK OFFSET(14) NUMBITS(1) [],
189 S_NOT_READY_DATA_NACK OFFSET(15) NUMBITS(1) [],
190 LOOPBACK OFFSET(16) NUMBITS(1) [],
191 SLAVE_MODE OFFSET(30) NUMBITS(1) [],
192 MASTER_MODE OFFSET(31) NUMBITS(1) []
193],
194I2C_STATUS [
195 BUS_BUSY OFFSET(0) NUMBITS(1) [],
196 I2C_EC_BUSY OFFSET(1) NUMBITS(1) [],
197 S_READ OFFSET(4) NUMBITS(1) [],
198 M_READ OFFSET(5) NUMBITS(1) [],
199 CURR_EZ_ADDR OFFSET(8) NUMBITS(8) [],
200 BASE_EZ_ADDR OFFSET(16) NUMBITS(8) []
201],
202I2C_M_CMD [
203 M_START OFFSET(0) NUMBITS(1) [],
204 M_START_ON_IDLE OFFSET(1) NUMBITS(1) [],
205 M_ACK OFFSET(2) NUMBITS(1) [],
206 M_NACK OFFSET(3) NUMBITS(1) [],
207 M_STOP OFFSET(4) NUMBITS(1) []
208],
209I2C_S_CMD [
210 S_ACK OFFSET(0) NUMBITS(1) [],
211 S_NACK OFFSET(1) NUMBITS(1) []
212],
213I2C_CFG [
214 SDA_IN_FILT_TRIM OFFSET(0) NUMBITS(2) [],
215 SDA_IN_FILT_SEL OFFSET(4) NUMBITS(1) [],
216 SCL_IN_FILT_TRIM OFFSET(8) NUMBITS(2) [],
217 SCL_IN_FILT_SEL OFFSET(12) NUMBITS(1) [],
218 SDA_OUT_FILT0_TRIM OFFSET(16) NUMBITS(2) [],
219 SDA_OUT_FILT1_TRIM OFFSET(18) NUMBITS(2) [],
220 SDA_OUT_FILT2_TRIM OFFSET(20) NUMBITS(2) [],
221 SDA_OUT_FILT_SEL OFFSET(28) NUMBITS(2) []
222],
223TX_CTRL [
224 DATA_WIDTH OFFSET(0) NUMBITS(4) [],
225 MSB_FIRST OFFSET(8) NUMBITS(1) [],
226 OPEN_DRAIN OFFSET(16) NUMBITS(1) []
227],
228TX_FIFO_CTRL [
229 TRIGGER_LEVEL OFFSET(0) NUMBITS(8) [],
230 CLEAR OFFSET(16) NUMBITS(1) [],
231 FREEZE OFFSET(17) NUMBITS(1) []
232],
233TX_FIFO_STATUS [
234 USED OFFSET(0) NUMBITS(9) [],
235 SR_VALID OFFSET(15) NUMBITS(1) [],
236 RD_PTR OFFSET(16) NUMBITS(8) [],
237 WR_PTR OFFSET(24) NUMBITS(8) []
238],
239TX_FIFO_WR [
240 DATA OFFSET(0) NUMBITS(16) []
241],
242RX_CTRL [
243 DATA_WIDTH OFFSET(0) NUMBITS(4) [],
244 MSB_FIRST OFFSET(8) NUMBITS(1) [],
245 MEDIAN OFFSET(9) NUMBITS(1) []
246],
247RX_FIFO_CTRL [
248 TRIGGER_LEVEL OFFSET(0) NUMBITS(8) [],
249 CLEAR OFFSET(16) NUMBITS(1) [],
250 FREEZE OFFSET(17) NUMBITS(1) []
251],
252RX_FIFO_STATUS [
253 USED OFFSET(0) NUMBITS(9) [],
254 SR_VALID OFFSET(15) NUMBITS(1) [],
255 RD_PTR OFFSET(16) NUMBITS(8) [],
256 WR_PTR OFFSET(24) NUMBITS(8) []
257],
258RX_MATCH [
259 ADDR OFFSET(0) NUMBITS(8) [],
260 MASK OFFSET(16) NUMBITS(8) []
261],
262RX_FIFO_RD [
263 DATA OFFSET(0) NUMBITS(16) []
264],
265RX_FIFO_RD_SILENT [
266 DATA OFFSET(0) NUMBITS(16) []
267],
268INTR_CAUSE [
269 M OFFSET(0) NUMBITS(1) [],
270 S OFFSET(1) NUMBITS(1) [],
271 TX OFFSET(2) NUMBITS(1) [],
272 RX OFFSET(3) NUMBITS(1) [],
273 I2C_EC OFFSET(4) NUMBITS(1) [],
274 SPI_EC OFFSET(5) NUMBITS(1) []
275],
276INTR_I2C_EC [
277 WAKE_UP OFFSET(0) NUMBITS(1) [],
278 EZ_STOP OFFSET(1) NUMBITS(1) [],
279 EZ_WRITE_STOP OFFSET(2) NUMBITS(1) [],
280 EZ_READ_STOP OFFSET(3) NUMBITS(1) []
281],
282INTR_I2C_EC_MASK [
283 WAKE_UP OFFSET(0) NUMBITS(1) [],
284 EZ_STOP OFFSET(1) NUMBITS(1) [],
285 EZ_WRITE_STOP OFFSET(2) NUMBITS(1) [],
286 EZ_READ_STOP OFFSET(3) NUMBITS(1) []
287],
288INTR_I2C_EC_MASKED [
289 WAKE_UP OFFSET(0) NUMBITS(1) [],
290 EZ_STOP OFFSET(1) NUMBITS(1) [],
291 EZ_WRITE_STOP OFFSET(2) NUMBITS(1) [],
292 EZ_READ_STOP OFFSET(3) NUMBITS(1) []
293],
294INTR_SPI_EC [
295 WAKE_UP OFFSET(0) NUMBITS(1) [],
296 EZ_STOP OFFSET(1) NUMBITS(1) [],
297 EZ_WRITE_STOP OFFSET(2) NUMBITS(1) [],
298 EZ_READ_STOP OFFSET(3) NUMBITS(1) []
299],
300INTR_SPI_EC_MASK [
301 WAKE_UP OFFSET(0) NUMBITS(1) [],
302 EZ_STOP OFFSET(1) NUMBITS(1) [],
303 EZ_WRITE_STOP OFFSET(2) NUMBITS(1) [],
304 EZ_READ_STOP OFFSET(3) NUMBITS(1) []
305],
306INTR_SPI_EC_MASKED [
307 WAKE_UP OFFSET(0) NUMBITS(1) [],
308 EZ_STOP OFFSET(1) NUMBITS(1) [],
309 EZ_WRITE_STOP OFFSET(2) NUMBITS(1) [],
310 EZ_READ_STOP OFFSET(3) NUMBITS(1) []
311],
312INTR_M [
313 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
314 I2C_NACK OFFSET(1) NUMBITS(1) [],
315 I2C_ACK OFFSET(2) NUMBITS(1) [],
316 I2C_STOP OFFSET(4) NUMBITS(1) [],
317 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
318 SPI_DONE OFFSET(9) NUMBITS(1) []
319],
320INTR_M_SET [
321 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
322 I2C_NACK OFFSET(1) NUMBITS(1) [],
323 I2C_ACK OFFSET(2) NUMBITS(1) [],
324 I2C_STOP OFFSET(4) NUMBITS(1) [],
325 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
326 SPI_DONE OFFSET(9) NUMBITS(1) []
327],
328INTR_M_MASK [
329 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
330 I2C_NACK OFFSET(1) NUMBITS(1) [],
331 I2C_ACK OFFSET(2) NUMBITS(1) [],
332 I2C_STOP OFFSET(4) NUMBITS(1) [],
333 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
334 SPI_DONE OFFSET(9) NUMBITS(1) []
335],
336INTR_M_MASKED [
337 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
338 I2C_NACK OFFSET(1) NUMBITS(1) [],
339 I2C_ACK OFFSET(2) NUMBITS(1) [],
340 I2C_STOP OFFSET(4) NUMBITS(1) [],
341 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
342 SPI_DONE OFFSET(9) NUMBITS(1) []
343],
344INTR_S [
345 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
346 I2C_NACK OFFSET(1) NUMBITS(1) [],
347 I2C_ACK OFFSET(2) NUMBITS(1) [],
348 I2C_WRITE_STOP OFFSET(3) NUMBITS(1) [],
349 I2C_STOP OFFSET(4) NUMBITS(1) [],
350 I2C_START OFFSET(5) NUMBITS(1) [],
351 I2C_ADDR_MATCH OFFSET(6) NUMBITS(1) [],
352 I2C_GENERAL OFFSET(7) NUMBITS(1) [],
353 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
354 SPI_EZ_WRITE_STOP OFFSET(9) NUMBITS(1) [],
355 SPI_EZ_STOP OFFSET(10) NUMBITS(1) [],
356 SPI_BUS_ERROR OFFSET(11) NUMBITS(1) []
357],
358INTR_S_SET [
359 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
360 I2C_NACK OFFSET(1) NUMBITS(1) [],
361 I2C_ACK OFFSET(2) NUMBITS(1) [],
362 I2C_WRITE_STOP OFFSET(3) NUMBITS(1) [],
363 I2C_STOP OFFSET(4) NUMBITS(1) [],
364 I2C_START OFFSET(5) NUMBITS(1) [],
365 I2C_ADDR_MATCH OFFSET(6) NUMBITS(1) [],
366 I2C_GENERAL OFFSET(7) NUMBITS(1) [],
367 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
368 SPI_EZ_WRITE_STOP OFFSET(9) NUMBITS(1) [],
369 SPI_EZ_STOP OFFSET(10) NUMBITS(1) [],
370 SPI_BUS_ERROR OFFSET(11) NUMBITS(1) []
371],
372INTR_S_MASK [
373 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
374 I2C_NACK OFFSET(1) NUMBITS(1) [],
375 I2C_ACK OFFSET(2) NUMBITS(1) [],
376 I2C_WRITE_STOP OFFSET(3) NUMBITS(1) [],
377 I2C_STOP OFFSET(4) NUMBITS(1) [],
378 I2C_START OFFSET(5) NUMBITS(1) [],
379 I2C_ADDR_MATCH OFFSET(6) NUMBITS(1) [],
380 I2C_GENERAL OFFSET(7) NUMBITS(1) [],
381 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
382 SPI_EZ_WRITE_STOP OFFSET(9) NUMBITS(1) [],
383 SPI_EZ_STOP OFFSET(10) NUMBITS(1) [],
384 SPI_BUS_ERROR OFFSET(11) NUMBITS(1) []
385],
386INTR_S_MASKED [
387 I2C_ARB_LOST OFFSET(0) NUMBITS(1) [],
388 I2C_NACK OFFSET(1) NUMBITS(1) [],
389 I2C_ACK OFFSET(2) NUMBITS(1) [],
390 I2C_WRITE_STOP OFFSET(3) NUMBITS(1) [],
391 I2C_STOP OFFSET(4) NUMBITS(1) [],
392 I2C_START OFFSET(5) NUMBITS(1) [],
393 I2C_ADDR_MATCH OFFSET(6) NUMBITS(1) [],
394 I2C_GENERAL OFFSET(7) NUMBITS(1) [],
395 I2C_BUS_ERROR OFFSET(8) NUMBITS(1) [],
396 SPI_EZ_WRITE_STOP OFFSET(9) NUMBITS(1) [],
397 SPI_EZ_STOP OFFSET(10) NUMBITS(1) [],
398 SPI_BUS_ERROR OFFSET(11) NUMBITS(1) []
399],
400INTR_TX [
401 TRIGGER OFFSET(0) NUMBITS(1) [],
402 NOT_FULL OFFSET(1) NUMBITS(1) [],
403 EMPTY OFFSET(4) NUMBITS(1) [],
404 OVERFLOW OFFSET(5) NUMBITS(1) [],
405 UNDERFLOW OFFSET(6) NUMBITS(1) [],
406 BLOCKED OFFSET(7) NUMBITS(1) [],
407 UART_NACK OFFSET(8) NUMBITS(1) [],
408 UART_DONE OFFSET(9) NUMBITS(1) [],
409 UART_ARB_LOST OFFSET(10) NUMBITS(1) []
410],
411INTR_TX_SET [
412 TRIGGER OFFSET(0) NUMBITS(1) [],
413 NOT_FULL OFFSET(1) NUMBITS(1) [],
414 EMPTY OFFSET(4) NUMBITS(1) [],
415 OVERFLOW OFFSET(5) NUMBITS(1) [],
416 UNDERFLOW OFFSET(6) NUMBITS(1) [],
417 BLOCKED OFFSET(7) NUMBITS(1) [],
418 UART_NACK OFFSET(8) NUMBITS(1) [],
419 UART_DONE OFFSET(9) NUMBITS(1) [],
420 UART_ARB_LOST OFFSET(10) NUMBITS(1) []
421],
422INTR_TX_MASK [
423 TRIGGER OFFSET(0) NUMBITS(1) [],
424 NOT_FULL OFFSET(1) NUMBITS(1) [],
425 EMPTY OFFSET(4) NUMBITS(1) [],
426 OVERFLOW OFFSET(5) NUMBITS(1) [],
427 UNDERFLOW OFFSET(6) NUMBITS(1) [],
428 BLOCKED OFFSET(7) NUMBITS(1) [],
429 UART_NACK OFFSET(8) NUMBITS(1) [],
430 UART_DONE OFFSET(9) NUMBITS(1) [],
431 UART_ARB_LOST OFFSET(10) NUMBITS(1) []
432],
433INTR_TX_MASKED [
434 TRIGGER OFFSET(0) NUMBITS(1) [],
435 NOT_FULL OFFSET(1) NUMBITS(1) [],
436 EMPTY OFFSET(4) NUMBITS(1) [],
437 OVERFLOW OFFSET(5) NUMBITS(1) [],
438 UNDERFLOW OFFSET(6) NUMBITS(1) [],
439 BLOCKED OFFSET(7) NUMBITS(1) [],
440 UART_NACK OFFSET(8) NUMBITS(1) [],
441 UART_DONE OFFSET(9) NUMBITS(1) [],
442 UART_ARB_LOST OFFSET(10) NUMBITS(1) []
443],
444INTR_RX [
445 TRIGGER OFFSET(0) NUMBITS(1) [],
446 NOT_EMPTY OFFSET(2) NUMBITS(1) [],
447 FULL OFFSET(3) NUMBITS(1) [],
448 OVERFLOW OFFSET(5) NUMBITS(1) [],
449 UNDERFLOW OFFSET(6) NUMBITS(1) [],
450 BLOCKED OFFSET(7) NUMBITS(1) [],
451 FRAME_ERROR OFFSET(8) NUMBITS(1) [],
452 PARITY_ERROR OFFSET(9) NUMBITS(1) [],
453 BAUD_DETECT OFFSET(10) NUMBITS(1) [],
454 BREAK_DETECT OFFSET(11) NUMBITS(1) []
455],
456INTR_RX_SET [
457 TRIGGER OFFSET(0) NUMBITS(1) [],
458 NOT_EMPTY OFFSET(2) NUMBITS(1) [],
459 FULL OFFSET(3) NUMBITS(1) [],
460 OVERFLOW OFFSET(5) NUMBITS(1) [],
461 UNDERFLOW OFFSET(6) NUMBITS(1) [],
462 BLOCKED OFFSET(7) NUMBITS(1) [],
463 FRAME_ERROR OFFSET(8) NUMBITS(1) [],
464 PARITY_ERROR OFFSET(9) NUMBITS(1) [],
465 BAUD_DETECT OFFSET(10) NUMBITS(1) [],
466 BREAK_DETECT OFFSET(11) NUMBITS(1) []
467],
468INTR_RX_MASK [
469 TRIGGER OFFSET(0) NUMBITS(1) [],
470 NOT_EMPTY OFFSET(2) NUMBITS(1) [],
471 FULL OFFSET(3) NUMBITS(1) [],
472 OVERFLOW OFFSET(5) NUMBITS(1) [],
473 UNDERFLOW OFFSET(6) NUMBITS(1) [],
474 BLOCKED OFFSET(7) NUMBITS(1) [],
475 FRAME_ERROR OFFSET(8) NUMBITS(1) [],
476 PARITY_ERROR OFFSET(9) NUMBITS(1) [],
477 BAUD_DETECT OFFSET(10) NUMBITS(1) [],
478 BREAK_DETECT OFFSET(11) NUMBITS(1) []
479],
480INTR_RX_MASKED [
481 TRIGGER OFFSET(0) NUMBITS(1) [],
482 NOT_EMPTY OFFSET(2) NUMBITS(1) [],
483 FULL OFFSET(3) NUMBITS(1) [],
484 OVERFLOW OFFSET(5) NUMBITS(1) [],
485 UNDERFLOW OFFSET(6) NUMBITS(1) [],
486 BLOCKED OFFSET(7) NUMBITS(1) [],
487 FRAME_ERROR OFFSET(8) NUMBITS(1) [],
488 PARITY_ERROR OFFSET(9) NUMBITS(1) [],
489 BAUD_DETECT OFFSET(10) NUMBITS(1) [],
490 BREAK_DETECT OFFSET(11) NUMBITS(1) []
491]
492];
493const SCB5_BASE: StaticRef<Scb5Registers> =
494 unsafe { StaticRef::new(0x40650000 as *const Scb5Registers) };
495
496pub struct Scb<'a> {
497 registers: StaticRef<Scb5Registers>,
498
499 tx_client: OptionalCell<&'a dyn TransmitClient>,
500 tx_buffer: TakeCell<'static, [u8]>,
501 tx_length: OptionalCell<NonZeroUsize>,
502 tx_position: Cell<usize>,
503
504 rx_client: OptionalCell<&'a dyn ReceiveClient>,
505 rx_buffer: TakeCell<'static, [u8]>,
506 rx_length: OptionalCell<NonZeroUsize>,
507 rx_position: Cell<usize>,
508}
509
510impl Scb<'_> {
511 pub const fn new() -> Self {
512 Self {
513 registers: SCB5_BASE,
514
515 tx_client: OptionalCell::empty(),
516 tx_buffer: TakeCell::empty(),
517 tx_length: OptionalCell::empty(),
518 tx_position: Cell::new(0),
519
520 rx_client: OptionalCell::empty(),
521 rx_buffer: TakeCell::empty(),
522 rx_length: OptionalCell::empty(),
523 rx_position: Cell::new(0),
524 }
525 }
526
527 pub fn enable_tx_interrupts(&self) {
528 self.registers
529 .intr_tx_mask
530 .modify(INTR_TX_MASK::UART_DONE::SET);
531 }
532
533 pub fn disable_tx_interrupts(&self) {
534 self.registers
535 .intr_tx_mask
536 .modify(INTR_TX_MASK::UART_DONE::CLEAR);
537 }
538
539 pub fn enable_rx_interrupts(&self) {
540 self.registers
541 .intr_rx_mask
542 .modify(INTR_RX_MASK::NOT_EMPTY::SET);
543 }
544
545 pub fn disable_rx_interrupts(&self) {
546 self.registers
547 .intr_rx_mask
548 .modify(INTR_RX_MASK::NOT_EMPTY::CLEAR);
549 }
550
551 pub(crate) fn handle_interrupt(&self) {
552 if self.registers.intr_tx.is_set(INTR_TX::UART_DONE) {
553 self.disable_tx_interrupts();
554 self.registers.intr_tx.modify(INTR_TX::UART_DONE::SET);
555 match self.tx_length.get() {
557 None => return,
558 Some(_) => (),
559 }
560 let tx_length = self.tx_length.get().unwrap().get();
561 if tx_length == self.tx_position.get() + 1 {
562 self.tx_length.clear();
563 self.tx_client.map(|client| {
565 client.transmitted_buffer(self.tx_buffer.take().unwrap(), tx_length, Ok(()))
566 });
567 } else {
568 let current_position = self.tx_position.get();
569 self.tx_buffer.map(|buffer| {
571 self.registers.tx_fifo_wr.write(
572 TX_FIFO_WR::DATA.val(*buffer.get(current_position + 1).unwrap() as u32),
573 )
574 });
575 self.tx_position.set(current_position + 1);
576 self.enable_tx_interrupts();
577 }
578 }
579 if self.registers.intr_rx.is_set(INTR_RX::NOT_EMPTY) {
580 let byte = self.registers.rx_fifo_rd.read(RX_FIFO_RD::DATA) as u8;
581 self.registers.intr_rx.modify(INTR_RX::NOT_EMPTY::SET);
583 if let Some(rx_buffer) = self.rx_buffer.take() {
586 let mut current_position = self.rx_position.get();
587 rx_buffer[current_position] = byte;
588 current_position += 1;
589 let rx_length = self.rx_length.get().unwrap().get();
591 if current_position == rx_length {
592 self.rx_length.clear();
593 self.rx_client.map(|client| {
594 client.received_buffer(
595 rx_buffer,
596 rx_length,
597 Ok(()),
598 kernel::hil::uart::Error::None,
599 )
600 });
601 } else {
602 self.rx_position.set(current_position);
603 self.rx_buffer.replace(rx_buffer);
604 }
605 }
606 }
607 }
608
609 pub fn set_standard_uart_mode(&self) {
610 self.registers
611 .ctrl
612 .modify(CTRL::MODE::UniversalAsynchronousReceiverTransmitterUARTMode);
613 self.registers
614 .ctrl
615 .modify(CTRL::OVS.val(14) + CTRL::EC_AM_MODE.val(0) + CTRL::EC_OP_MODE.val(0));
616 self.registers
617 .uart_ctrl
618 .modify(UART_CTRL::MODE::StandardUARTSubmode);
619 self.registers
620 .uart_rx_ctrl
621 .modify(UART_RX_CTRL::MP_MODE::CLEAR + UART_RX_CTRL::LIN_MODE::CLEAR);
622
623 self.set_uart_sync();
624 }
625
626 pub fn enable_scb(&self) {
627 self.registers.ctrl.modify(CTRL::ENABLED::SET);
628 }
629
630 pub fn disable_scb(&self) {
631 self.registers.ctrl.modify(CTRL::ENABLED::CLEAR);
632 }
633
634 fn set_uart_sync(&self) {
635 self.registers.ctrl.modify(CTRL::BYTE_MODE::SET);
636 self.registers
637 .tx_ctrl
638 .modify(TX_CTRL::DATA_WIDTH.val(7) + TX_CTRL::MSB_FIRST::CLEAR);
639
640 self.registers
641 .rx_ctrl
642 .modify(RX_CTRL::DATA_WIDTH.val(7) + RX_CTRL::MSB_FIRST::CLEAR);
643
644 self.registers.tx_fifo_wr.write(TX_FIFO_WR::DATA.val(0));
645
646 self.registers
647 .tx_fifo_ctrl
648 .modify(TX_FIFO_CTRL::TRIGGER_LEVEL.val(1));
649 self.registers.tx_fifo_ctrl.modify(TX_FIFO_CTRL::CLEAR::SET);
650 while !self.uart_is_transmitter_done() {}
651 self.registers
652 .tx_fifo_ctrl
653 .modify(TX_FIFO_CTRL::CLEAR::CLEAR);
654
655 self.registers
656 .rx_fifo_ctrl
657 .modify(RX_FIFO_CTRL::TRIGGER_LEVEL.val(1));
658 self.registers.rx_fifo_ctrl.modify(RX_FIFO_CTRL::CLEAR::SET);
659 self.registers
660 .rx_fifo_ctrl
661 .modify(RX_FIFO_CTRL::CLEAR::CLEAR);
662
663 self.registers
664 .uart_tx_ctrl
665 .modify(UART_TX_CTRL::PARITY::CLEAR);
666 self.registers
667 .uart_tx_ctrl
668 .modify(UART_TX_CTRL::STOP_BITS.val(1));
669
670 self.registers
671 .uart_rx_ctrl
672 .modify(UART_RX_CTRL::PARITY::CLEAR);
673 self.registers
674 .uart_rx_ctrl
675 .modify(UART_RX_CTRL::STOP_BITS.val(1));
676
677 self.registers
678 .uart_flow_ctrl
679 .modify(UART_FLOW_CTRL::CTS_ENABLED::CLEAR);
680 }
681
682 fn uart_is_transmitter_done(&self) -> bool {
683 self.registers.tx_fifo_status.read(TX_FIFO_STATUS::SR_VALID) == 0
684 }
685
686 pub fn transmit_uart_sync(&self, buffer: &[u8]) {
687 for byte in buffer {
688 self.registers
689 .tx_fifo_wr
690 .write(TX_FIFO_WR::DATA.val(*byte as u32));
691
692 while !self.uart_is_transmitter_done() {}
693 }
694 }
695
696 pub fn transmit_uart_async(
697 &self,
698 buffer: &'static mut [u8],
699 buffer_len: usize,
700 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
701 if self.tx_length.is_some() {
702 Err((ErrorCode::BUSY, buffer))
703 } else if buffer.len() < buffer_len || buffer_len == 0 {
704 Err((ErrorCode::SIZE, buffer))
705 } else {
706 match NonZeroUsize::new(buffer_len) {
707 Some(tx_length) => {
708 self.registers
709 .tx_fifo_wr
710 .write(TX_FIFO_WR::DATA.val(*buffer.get(0).unwrap() as u32));
711 self.tx_buffer.put(Some(buffer));
712 self.tx_length.set(tx_length);
713 self.tx_position.set(0);
714 self.enable_tx_interrupts();
715 Ok(())
716 }
717 None => Err((ErrorCode::SIZE, buffer)),
718 }
719 }
720 }
721
722 pub fn receive_uart_async(
723 &self,
724 buffer: &'static mut [u8],
725 buffer_len: usize,
726 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
727 if self.rx_length.is_some() {
728 Err((ErrorCode::BUSY, buffer))
729 } else if buffer.len() < buffer_len || buffer_len == 0 {
730 Err((ErrorCode::SIZE, buffer))
731 } else {
732 match NonZeroUsize::new(buffer_len) {
733 Some(rx_length) => {
734 self.enable_rx_interrupts();
735 self.rx_buffer.put(Some(buffer));
736 self.rx_length.set(rx_length);
737 self.rx_position.set(0);
738 Ok(())
739 }
740 None => Err((ErrorCode::SIZE, buffer)),
741 }
742 }
743 }
744}
745
746impl<'a> Transmit<'a> for Scb<'a> {
747 fn set_transmit_client(&self, client: &'a dyn TransmitClient) {
748 self.tx_client.set(client);
749 }
750
751 fn transmit_buffer(
752 &self,
753 tx_buffer: &'static mut [u8],
754 tx_len: usize,
755 ) -> Result<(), (kernel::ErrorCode, &'static mut [u8])> {
756 self.transmit_uart_async(tx_buffer, tx_len)
757 }
758
759 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
760 Err(ErrorCode::NOSUPPORT)
761 }
762
763 fn transmit_abort(&self) -> Result<(), ErrorCode> {
764 Err(ErrorCode::NOSUPPORT)
765 }
766}
767
768impl<'a> Receive<'a> for Scb<'a> {
769 fn set_receive_client(&self, client: &'a dyn ReceiveClient) {
770 self.rx_client.set(client);
771 }
772
773 fn receive_buffer(
774 &self,
775 rx_buffer: &'static mut [u8],
776 rx_len: usize,
777 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
778 self.receive_uart_async(rx_buffer, rx_len)
779 }
780
781 fn receive_word(&self) -> Result<(), ErrorCode> {
782 Err(ErrorCode::NOSUPPORT)
783 }
784
785 fn receive_abort(&self) -> Result<(), ErrorCode> {
786 Err(ErrorCode::NOSUPPORT)
787 }
788}
789
790impl Configure for Scb<'_> {
791 fn configure(&self, params: kernel::hil::uart::Parameters) -> Result<(), ErrorCode> {
792 if params.baud_rate != 115200 || params.hw_flow_control {
793 Err(ErrorCode::NOSUPPORT)
794 } else {
795 if self.registers.ctrl.is_set(CTRL::ENABLED) {
797 return Err(ErrorCode::BUSY);
798 }
799 match params.stop_bits {
800 uart::StopBits::One => {
801 self.registers
802 .uart_tx_ctrl
803 .modify(UART_TX_CTRL::STOP_BITS.val(1));
804 self.registers
805 .uart_rx_ctrl
806 .modify(UART_RX_CTRL::STOP_BITS.val(1));
807 }
808 uart::StopBits::Two => {
809 self.registers
810 .uart_tx_ctrl
811 .modify(UART_TX_CTRL::STOP_BITS.val(3));
812 self.registers
813 .uart_rx_ctrl
814 .modify(UART_RX_CTRL::STOP_BITS.val(3));
815 }
816 }
817 match params.parity {
818 uart::Parity::None => {
819 self.registers
820 .uart_tx_ctrl
821 .modify(UART_TX_CTRL::PARITY_ENABLED::CLEAR);
822 self.registers
823 .uart_rx_ctrl
824 .modify(UART_RX_CTRL::PARITY_ENABLED::CLEAR);
825 }
826 uart::Parity::Odd => {
827 self.registers
828 .uart_tx_ctrl
829 .modify(UART_TX_CTRL::PARITY_ENABLED::SET + UART_TX_CTRL::PARITY::SET);
830 self.registers
831 .uart_rx_ctrl
832 .modify(UART_RX_CTRL::PARITY_ENABLED::SET + UART_RX_CTRL::PARITY::SET);
833 }
834 uart::Parity::Even => {
835 self.registers
836 .uart_tx_ctrl
837 .modify(UART_TX_CTRL::PARITY_ENABLED::SET + UART_TX_CTRL::PARITY::CLEAR);
838 self.registers
839 .uart_rx_ctrl
840 .modify(UART_RX_CTRL::PARITY_ENABLED::SET + UART_RX_CTRL::PARITY::CLEAR);
841 }
842 }
843 match params.width {
844 uart::Width::Six => {
845 self.registers.tx_ctrl.modify(TX_CTRL::DATA_WIDTH.val(5));
846 }
847 uart::Width::Seven => {
848 self.registers.tx_ctrl.modify(TX_CTRL::DATA_WIDTH.val(6));
849 }
850 uart::Width::Eight => {
851 self.registers.tx_ctrl.modify(TX_CTRL::DATA_WIDTH.val(7));
852 }
853 }
854 Ok(())
855 }
856 }
857}