psoc62xa/
scb.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright OxidOS Automotive 2025 SRL.
4
5use 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            // SAFETY: When a transmit is started, length is set to a non-zero value.
556            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                // SAFETY: When a transmit is started, a buffer is passed.
564                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                // SAFETY: Because of the if condition, current_position + 1 < buffer.len().
570                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            // The caller must ensure that the FIFO buffer is empty before clearing the interrupt.
582            self.registers.intr_rx.modify(INTR_RX::NOT_EMPTY::SET);
583            // If no rx_buffer is set, then no reception is pending. Simply discard the received
584            // byte.
585            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                // SAFETY: When a read is started, rx_length is set to a non-zero value.
590                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            // Modification of the SCB parameters require it to be disabled.
796            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}