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 if self.tx_length.get().is_none() {
557 return;
558 }
559 let tx_length = self.tx_length.get().unwrap().get();
560 if tx_length == self.tx_position.get() + 1 {
561 self.tx_length.clear();
562 self.tx_client.map(|client| {
564 client.transmitted_buffer(self.tx_buffer.take().unwrap(), tx_length, Ok(()))
565 });
566 } else {
567 let current_position = self.tx_position.get();
568 self.tx_buffer.map(|buffer| {
570 self.registers.tx_fifo_wr.write(
571 TX_FIFO_WR::DATA.val(*buffer.get(current_position + 1).unwrap() as u32),
572 )
573 });
574 self.tx_position.set(current_position + 1);
575 self.enable_tx_interrupts();
576 }
577 }
578 if self.registers.intr_rx.is_set(INTR_RX::NOT_EMPTY) {
579 let byte = self.registers.rx_fifo_rd.read(RX_FIFO_RD::DATA) as u8;
580 self.registers.intr_rx.modify(INTR_RX::NOT_EMPTY::SET);
582 if let Some(rx_buffer) = self.rx_buffer.take() {
585 let mut current_position = self.rx_position.get();
586 rx_buffer[current_position] = byte;
587 current_position += 1;
588 let rx_length = self.rx_length.get().unwrap().get();
590 if current_position == rx_length {
591 self.rx_length.clear();
592 self.rx_client.map(|client| {
593 client.received_buffer(
594 rx_buffer,
595 rx_length,
596 Ok(()),
597 kernel::hil::uart::Error::None,
598 )
599 });
600 } else {
601 self.rx_position.set(current_position);
602 self.rx_buffer.replace(rx_buffer);
603 }
604 }
605 }
606 }
607
608 pub fn set_standard_uart_mode(&self) {
609 self.registers
610 .ctrl
611 .modify(CTRL::MODE::UniversalAsynchronousReceiverTransmitterUARTMode);
612 self.registers
613 .ctrl
614 .modify(CTRL::OVS.val(14) + CTRL::EC_AM_MODE.val(0) + CTRL::EC_OP_MODE.val(0));
615 self.registers
616 .uart_ctrl
617 .modify(UART_CTRL::MODE::StandardUARTSubmode);
618 self.registers
619 .uart_rx_ctrl
620 .modify(UART_RX_CTRL::MP_MODE::CLEAR + UART_RX_CTRL::LIN_MODE::CLEAR);
621
622 self.set_uart_sync();
623 }
624
625 pub fn enable_scb(&self) {
626 self.registers.ctrl.modify(CTRL::ENABLED::SET);
627 }
628
629 pub fn disable_scb(&self) {
630 self.registers.ctrl.modify(CTRL::ENABLED::CLEAR);
631 }
632
633 fn set_uart_sync(&self) {
634 self.registers.ctrl.modify(CTRL::BYTE_MODE::SET);
635 self.registers
636 .tx_ctrl
637 .modify(TX_CTRL::DATA_WIDTH.val(7) + TX_CTRL::MSB_FIRST::CLEAR);
638
639 self.registers
640 .rx_ctrl
641 .modify(RX_CTRL::DATA_WIDTH.val(7) + RX_CTRL::MSB_FIRST::CLEAR);
642
643 self.registers.tx_fifo_wr.write(TX_FIFO_WR::DATA.val(0));
644
645 self.registers
646 .tx_fifo_ctrl
647 .modify(TX_FIFO_CTRL::TRIGGER_LEVEL.val(1));
648 self.registers.tx_fifo_ctrl.modify(TX_FIFO_CTRL::CLEAR::SET);
649 while !self.uart_is_transmitter_done() {}
650 self.registers
651 .tx_fifo_ctrl
652 .modify(TX_FIFO_CTRL::CLEAR::CLEAR);
653
654 self.registers
655 .rx_fifo_ctrl
656 .modify(RX_FIFO_CTRL::TRIGGER_LEVEL.val(1));
657 self.registers.rx_fifo_ctrl.modify(RX_FIFO_CTRL::CLEAR::SET);
658 self.registers
659 .rx_fifo_ctrl
660 .modify(RX_FIFO_CTRL::CLEAR::CLEAR);
661
662 self.registers
663 .uart_tx_ctrl
664 .modify(UART_TX_CTRL::PARITY::CLEAR);
665 self.registers
666 .uart_tx_ctrl
667 .modify(UART_TX_CTRL::STOP_BITS.val(1));
668
669 self.registers
670 .uart_rx_ctrl
671 .modify(UART_RX_CTRL::PARITY::CLEAR);
672 self.registers
673 .uart_rx_ctrl
674 .modify(UART_RX_CTRL::STOP_BITS.val(1));
675
676 self.registers
677 .uart_flow_ctrl
678 .modify(UART_FLOW_CTRL::CTS_ENABLED::CLEAR);
679 }
680
681 fn uart_is_transmitter_done(&self) -> bool {
682 self.registers.tx_fifo_status.read(TX_FIFO_STATUS::SR_VALID) == 0
683 }
684
685 pub fn transmit_uart_sync(&self, buffer: &[u8]) {
686 for byte in buffer {
687 self.registers
688 .tx_fifo_wr
689 .write(TX_FIFO_WR::DATA.val(*byte as u32));
690
691 while !self.uart_is_transmitter_done() {}
692 }
693 }
694
695 pub fn transmit_uart_async(
696 &self,
697 buffer: &'static mut [u8],
698 buffer_len: usize,
699 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
700 if self.tx_length.is_some() {
701 Err((ErrorCode::BUSY, buffer))
702 } else if buffer.len() < buffer_len || buffer_len == 0 {
703 Err((ErrorCode::SIZE, buffer))
704 } else {
705 match NonZeroUsize::new(buffer_len) {
706 Some(tx_length) => {
707 self.registers
708 .tx_fifo_wr
709 .write(TX_FIFO_WR::DATA.val(*buffer.get(0).unwrap() as u32));
710 self.tx_buffer.put(Some(buffer));
711 self.tx_length.set(tx_length);
712 self.tx_position.set(0);
713 self.enable_tx_interrupts();
714 Ok(())
715 }
716 None => Err((ErrorCode::SIZE, buffer)),
717 }
718 }
719 }
720
721 pub fn receive_uart_async(
722 &self,
723 buffer: &'static mut [u8],
724 buffer_len: usize,
725 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
726 if self.rx_length.is_some() {
727 Err((ErrorCode::BUSY, buffer))
728 } else if buffer.len() < buffer_len || buffer_len == 0 {
729 Err((ErrorCode::SIZE, buffer))
730 } else {
731 match NonZeroUsize::new(buffer_len) {
732 Some(rx_length) => {
733 self.enable_rx_interrupts();
734 self.rx_buffer.put(Some(buffer));
735 self.rx_length.set(rx_length);
736 self.rx_position.set(0);
737 Ok(())
738 }
739 None => Err((ErrorCode::SIZE, buffer)),
740 }
741 }
742 }
743}
744
745impl<'a> Transmit<'a> for Scb<'a> {
746 fn set_transmit_client(&self, client: &'a dyn TransmitClient) {
747 self.tx_client.set(client);
748 }
749
750 fn transmit_buffer(
751 &self,
752 tx_buffer: &'static mut [u8],
753 tx_len: usize,
754 ) -> Result<(), (kernel::ErrorCode, &'static mut [u8])> {
755 self.transmit_uart_async(tx_buffer, tx_len)
756 }
757
758 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
759 Err(ErrorCode::NOSUPPORT)
760 }
761
762 fn transmit_abort(&self) -> Result<(), ErrorCode> {
763 Err(ErrorCode::NOSUPPORT)
764 }
765}
766
767impl<'a> Receive<'a> for Scb<'a> {
768 fn set_receive_client(&self, client: &'a dyn ReceiveClient) {
769 self.rx_client.set(client);
770 }
771
772 fn receive_buffer(
773 &self,
774 rx_buffer: &'static mut [u8],
775 rx_len: usize,
776 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
777 self.receive_uart_async(rx_buffer, rx_len)
778 }
779
780 fn receive_word(&self) -> Result<(), ErrorCode> {
781 Err(ErrorCode::NOSUPPORT)
782 }
783
784 fn receive_abort(&self) -> Result<(), ErrorCode> {
785 Err(ErrorCode::NOSUPPORT)
786 }
787}
788
789impl Configure for Scb<'_> {
790 fn configure(&self, params: kernel::hil::uart::Parameters) -> Result<(), ErrorCode> {
791 if params.baud_rate != 115200 || params.hw_flow_control {
792 Err(ErrorCode::NOSUPPORT)
793 } else {
794 if self.registers.ctrl.is_set(CTRL::ENABLED) {
796 return Err(ErrorCode::BUSY);
797 }
798 match params.stop_bits {
799 uart::StopBits::One => {
800 self.registers
801 .uart_tx_ctrl
802 .modify(UART_TX_CTRL::STOP_BITS.val(1));
803 self.registers
804 .uart_rx_ctrl
805 .modify(UART_RX_CTRL::STOP_BITS.val(1));
806 }
807 uart::StopBits::Two => {
808 self.registers
809 .uart_tx_ctrl
810 .modify(UART_TX_CTRL::STOP_BITS.val(3));
811 self.registers
812 .uart_rx_ctrl
813 .modify(UART_RX_CTRL::STOP_BITS.val(3));
814 }
815 }
816 match params.parity {
817 uart::Parity::None => {
818 self.registers
819 .uart_tx_ctrl
820 .modify(UART_TX_CTRL::PARITY_ENABLED::CLEAR);
821 self.registers
822 .uart_rx_ctrl
823 .modify(UART_RX_CTRL::PARITY_ENABLED::CLEAR);
824 }
825 uart::Parity::Odd => {
826 self.registers
827 .uart_tx_ctrl
828 .modify(UART_TX_CTRL::PARITY_ENABLED::SET + UART_TX_CTRL::PARITY::SET);
829 self.registers
830 .uart_rx_ctrl
831 .modify(UART_RX_CTRL::PARITY_ENABLED::SET + UART_RX_CTRL::PARITY::SET);
832 }
833 uart::Parity::Even => {
834 self.registers
835 .uart_tx_ctrl
836 .modify(UART_TX_CTRL::PARITY_ENABLED::SET + UART_TX_CTRL::PARITY::CLEAR);
837 self.registers
838 .uart_rx_ctrl
839 .modify(UART_RX_CTRL::PARITY_ENABLED::SET + UART_RX_CTRL::PARITY::CLEAR);
840 }
841 }
842 match params.width {
843 uart::Width::Six => {
844 self.registers.tx_ctrl.modify(TX_CTRL::DATA_WIDTH.val(5));
845 }
846 uart::Width::Seven => {
847 self.registers.tx_ctrl.modify(TX_CTRL::DATA_WIDTH.val(6));
848 }
849 uart::Width::Eight => {
850 self.registers.tx_ctrl.modify(TX_CTRL::DATA_WIDTH.val(7));
851 }
852 }
853 Ok(())
854 }
855 }
856}