Compare commits

...

4 Commits

@ -91,12 +91,14 @@ def task_install_dep():
def task_compile():
""" Compile the sources.
"""
return {
task = {
'file_dep': get_build_dep(),
'targets': [f'{consts.WORK_DIR}/target/{consts.TARGET}/release/kernel'],
'actions': [f'RUSTFLAGS="{consts.RUSTC_FLAGS}" cargo rustc --target={consts.TARGET} {consts.CARGO_COMPILE_FLAGS}'],
'clean': [f'cargo clean']
}
print(task)
return task
def task_build():
""" Strip the binary from ELF format to raw binary.

@ -262,260 +262,621 @@ pub const UART_START: usize = START_PHYSICAL_ADDRESS + UART_OFFSET;
pub mod uart {
use super::*;
/// Data Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R/W.
/// - 11: OE, Overrun Error. Set to 1 if data received with FIFO full, R/W.
/// - 10: BE, Break Error. Set to 1 if a break condition was detected, R/W.
/// - 9: PE, Parity Error. Set to 1 when the parity don't match data, R/W.
/// - 8: FE, Framing Error. Set to 1 when character don't have valid stop bit, R/W.
/// - 7-0: DATA, Data character. R/W.
pub const DR: usize = UART_START + 0x00;
/// Receive Status Register/Error Clear Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R/W.
/// - 3: OE, Overrun Error. Set to 1 if data received with FIFO full, R/W.
/// - 2: BE, Break Error. Set to 1 if a break condition was detected, R/W.
/// - 1: PE, Parity Error. Set to 1 when the parity don't match data, R/W.
/// - 0: FE, Framing Error. Set to 1 when characteur don't have valid stop bit, R/W.
pub const RSRECR: usize = UART_START + 0x04;
/// Flag register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-9: reserved. Write as 0, value read don't have meaning, R/W.
/// - 8: RI, unsuported. Write as 0, value read don't have meaning, R/W.
/// - 7: TXFE, Transmit FIFO Empty. If FIFO disabled, set when tx holding register empty.
/// If FIFO enabled, set when tx FIFP is empty. R/W.
/// - 6: RXFF, Receive FIFO Full. If FIFO disabled, set when rx holding register is full.
/// If FIFO enabled, set when rx FIFO is full. R/W.
/// - 5: TXFF, Transmit FIFO Full. If FIFO disabled, set when tx holding register full.
/// If FIFO enabled, set when tx FIFP is full. R/W.
/// - 4: RXFE, Receive FIFO Empty. If FIFO disabled, set when rx holding register is empty.
/// If FIFO enabled, set when rx FIFO is empty. R/W.
/// - 3: BUSY. Is set, UART is busy transmitting data. R/W.
/// - 2: DCD, unsuported. Write as 0, value read don't have meaning, R/W.
/// - 1: DSR, unsuported. Write as 0, value read don't have meaning, R/W.
/// - 0: CTS, Clear To Send.
pub const FR: usize = UART_START + 0x18;
/// Not in use. 32 bits long.
pub const ILPR: usize = UART_START + 0x20;
/// Integer Baud rate divisor, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-16: reserved. Write as 0, value read don't have meaning, R/W.
/// - 15-0: IBRD. The integer baud rate divisor, R/W.
pub const IBRD: usize = UART_START + 0x24;
/// Fractional Baud rate divisor, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-6: reserved. Write as 0, value read don't have meaning, R/W.
/// - 5-0: FBRD. The fractional baud rate divisor, R/W.
pub const FBRD: usize = UART_START + 0x28;
/// Line Constrol register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-8: reserved. Write as 0, value read don't have meaning, R/W.
/// - 7: SPS, Stick Parity Select. 0: the stick parity is disabled, 1: either
/// depending on EPS (Event Parity Select), R/W.
/// - 6-5: WLEN: World lenght. Number of data bits transmitted by frame (0b00 -> 5b, 0b11 ->
/// 8b), R/W.
/// - 4: FEN, Enable FIFOs. 0: FIFOs disabled, 1: FIFO buffers are enables, R/W.
/// - 3: STP2, 2 Stop bit select. 1: 2 stop bits are transmitted at the end of the frame
/// (rx logic is not affected), R/W.
/// - 2: EPS, Event Parity Select. 0: odd parity, check for odd number of 1 in data+parity
/// bits, 1: event parity, check for even number of 1 in data+parity. No effect when
/// PEN disable parity check. R/W.
/// - 1: PEN, Parity Enable. 0: Don't add parity bit and don't check parity, 1: add parity bit
/// and check for parity, R/W.
/// - 0: BRK: Send break. If set, send continuous low level to TXD after the current char, R/W.
pub const LCRH: usize = UART_START + 0x2C;
/// Control register, 32 bits long.
///
/// # Warning
///
/// To program the CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
///
/// # Bits distribution:
///
/// - 31-16: reserved. Write as 0, value read don't have meaning, R/W.
/// - 15: CTSEN, CTS hardware flow control enable. If set, data is only transmitted when
/// nUARTCTS is asserted, R/W.
/// - 14: RTSEN, RST hardware flow control enable. If set, data is only requested when there
/// is space in the receive FIFO, R/W.
/// - 13: OUT2, unsuported, Write as 0, value read don't have meaning, R.
/// - 12: OUT1, unsuported, Write as 0, value read don't have meaning, R.
/// - 11: RTS, Request To Send. When set to 1, nUARTRTS is low, R/W.
/// - 10: DTR, unsuported, Write as 0, value read don't have meaning, R.
/// - 9: RXE, Receive enable. If set, (and if UARTEN is set), the uart can read data, R/W.
/// - 8: TXE, Transmit enable. If set, (and if UARTEN is set), the uart can send data, R/W.
/// - 7: LBE, LoopBack Enable. If set, UARTTXD is fed through to the UARTRXD path, R/W.
/// - 6-3: reserved. Write as 0, value read don't have meaning, R/W.
/// - 2: SIRLP, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: SIREN, unsuported, Write as 0, value read don't have meaning, R.
/// - 0: UARTEN, UART enable. If set, the UART is enable, R/W.
pub const CR: usize = UART_START + 0x30;
/// Interrupt FIFO level Select register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R/W.
/// - 11-9: RXIFPSEL, unsuported, Write as 0, value read don't have meaning, R.
/// - 8-6: TXIFPSEL, unsuported, Write as 0, value read don't have meaning, R.
/// - 5-3: RXIFLSEL, Receive Interrupt FIFO Level Select. The level from which the
/// reveive interrupt is send:
/// - `0b000`: Send when FIFO becom 1/8 full
/// - `0b001`: Send when FIFO becom 1/4 full
/// - `0b010`: Send when FIFO becom 1/2 full
/// - `0b011`: Send when FIFO becom 3/4 full
/// - `0b100`: Send when FIFO becom 7/7 full
/// - Other values are reserved.
/// R/W.
/// - 2-0: TXIFLSEL, Transmit Interrupt FIFO Level Select. The level from which the
/// transmit interrupt is send:
/// - `0b000`: Send when FIFO becom 1/8 full
/// - `0b001`: Send when FIFO becom 1/4 full
/// - `0b010`: Send when FIFO becom 1/2 full
/// - `0b011`: Send when FIFO becom 3/4 full
/// - `0b100`: Send when FIFO becom 7/7 full
/// - Other values are reserved.
/// R/W.
pub const IFLS: usize = UART_START + 0x34;
/// Interupt Mask Set Clear register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R/W.
/// - 10: OEIM, Overrun Error Interrupt Mask. Value of the mask for OE Interrupt, R/W.
/// - 9: BEIM, Break Error Interrupt Mask. Value of the mask for BE Interrupt, R/W.
/// - 8: PEIM, Parity Error Interrupt Mask. Value of the mask for PE Interrupt, R/W.
/// - 7: FEIM, Framing Error Interrupt Mask. Value of the mask for FE Interrupt, R/W.
/// - 6: RT Interrupt, Receive Timeout Interrupt Mask. Value of the mask for RTIM, R/W.
/// - 5: TXIM, Transmit Interrupt Mask. Value of the mask for TX Interrupt, R/W.
/// - 4: RXIM, Receive Interrupt Mask. Value of the mask for RX Interrupt, R/W.
/// - 3: DSRMIM, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMIM, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMIM, nUARTCTS Modem Interrupt Mask. Value of the mask for CTS Interrupt, R/W.
/// - 0: RIMIM, unsuported, Write as 0, value read don't have meaning, R.
pub const IMSC: usize = UART_START + 0x38;
/// Raw Interupt Status register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10: OERIS, Overrun Error Raw Interrupt Status. Raw interrupt state of the OE Interrupt, R.
/// - 9: BERIS, Break Error Raw Interrupt Status. Raw interrupt state of the BE Interrupt, R.
/// - 8: PERIS, Parity Error Raw Interrupt Status. Raw interrupt state of the PE Interrupt, R.
/// - 7: FERIS, Framing Error Raw Interrupt Status. Raw interrupt state of the FE Interrupt, R.
/// - 6: RT Interrupt, Receive Timeout Raw Interrupt Status. Raw interrupt state of the RTRIS, R.
/// - 5: TXRIS, Transmit Raw Interrupt Status. Raw interrupt state of the TX Interrupt, R.
/// - 4: RXRIS, Receive Raw Interrupt Status. Raw interrupt state of the RX Interrupt, R.
/// - 3: DSRMRIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMRIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMRIS, nUARTCTS Modem Raw Interrupt Status. Raw interrupt state of the CTS Interrupt, R.
/// - 0: RRISIM, unsuported, Write as 0, value read don't have meaning, R.
pub const RIS: usize = UART_START + 0x3C;
/// Masked Interupt Status register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10: OEMIS, Overrun Error Masked Interrupt Status. Masked interrupt state of the OE Interrupt, R.
/// - 9: BEMIS, Break Error Masked Interrupt Status. Masked interrupt state of the BE Interrupt, R.
/// - 8: PEMIS, Parity Error Masked Interrupt Status. Masked interrupt state of the PE Interrupt, R.
/// - 7: FEMIS, Framing Error Masked Interrupt Status. Masked interrupt state of the FE Interrupt, R.
/// - 6: RT Interrupt, Receive Timeout Masked Interrupt Status. Masked interrupt state of the RTMIS, R.
/// - 5: TXMIS, Transmit Masked Interrupt Status. Masked interrupt state of the TX Interrupt, R.
/// - 4: RXMIS, Receive Masked Interrupt Status. Masked interrupt state of the RX Interrupt, R.
/// - 3: DSRMMIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMMIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMMIS, nUARTCTS Modem Masked Interrupt Status. Masked interrupt state of the CTS Interrupt, R.
/// - 0: RMISIM, unsuported, Write as 0, value read don't have meaning, R.
pub const MIS: usize = UART_START + 0x40;
/// Interupt Clear Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10: OEIC, Overrun Error Interrupt Clear. Clear the OE Interrupt, R.
/// - 9: BEIC, Break Error Interrupt Clear. Clear the BE Interrupt, R.
/// - 8: PEIC, Parity Error Interrupt Clear. Clear the PE Interrupt, R.
/// - 7: FEIC, Framing Error Interrupt Clear. Clear the FE Interrupt, R.
/// - 6: RT Interrupt, Receive Timeout Interrupt Clear. Clear the RTIC, R.
/// - 5: TXIC, Transmit Interrupt Clear. Clear the TX Interrupt, R.
/// - 4: RXIC, Receive Interrupt Clear. Clear the RX Interrupt, R.
/// - 3: DSRMIC, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMIC, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMIC, nUARTCTS Modem Interrupt Clear. Clear the CTS Interrupt, R.
/// - 0: RICIM, unsuported, Write as 0, value read don't have meaning, R.
pub const ICR: usize = UART_START + 0x44;
/// DMA Control Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-3: reserved. Write as 0, value read don't have meaning, R.
/// - 2: DMAONERR, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: TXDMAE, unsuported, Write as 0, value read don't have meaning, R.
/// - 0: RXDMAE, unsuported, Write as 0, value read don't have meaning, R.
pub const DMACR: usize = UART_START + 0x48;
/// Test Control register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-2: reserved. Write as 0, value read don't have meaning, R.
/// - 1: ITCR1, Test FIFO enable. If set, read/write directly to the FIFOs with TDR10_0, R/W.
/// - 0: ITCR0, Integration Test Enable. If set, the UART is placed in intergration test mode,
/// R/W.
pub const ITCR: usize = UART_START + 0x80;
/// Integration Test Input register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-4: reserved. Write as 0, value read don't have meaning, R.
/// - 3: ITIP3. Reads returns the value of nUARTCTS, R/W.
/// - 2-1: reserved. Write as 0, value read don't have meaning, R.
/// - 0: ITIP0. Reads the value of UARTRXD, R/W.
pub const ITIP: usize = UART_START + 0x84;
/// Integration Test Output register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R.
/// - 11: ITOP11, Intra-chip Output. Writes set the value to be driven on UARTLSINTR, Reads
/// returns the value of UARTLSINTR at the output of the test multiplexor, R/W.
/// - 10: ITOP10, Intra-chip Output. Writes set the value to be driven on UARTRXINTR, Reads
/// returns the value of UARTRXINTR at the output of the test multiplexor, R/W.
/// - 9: ITOP9, Intra-chip Output. Writes set the value to be driven on UARTTXINTR, Reads
/// returns the value of UARTTXINTR at the output of the test multiplexor, R/W.
/// - 8: ITOP8, Intra-chip Output. Writes set the value to be driven on UARTRTINTR, Reads
/// returns the value of UARTRTINTR at the output of the test multiplexor, R/W.
/// - 7: ITOP7, Intra-chip Output. Writes set the value to be driven on UARTEINTR, Reads
/// returns the value of UARTEINTR at the output of the test multiplexor, R/W.
/// - 6: ITOP6, Intra-chip Output. Writes set the value to be driven on UARTINTR, Reads
/// returns the value of UARTINTR at the output of the test multiplexor, R/W.
/// - 5-4: reserved. Write as 0, value read don't have meaning, R.
/// - 3: ITIP3: Primary Output. Writes specify the value on nUARTRTS, R/W.
/// - 2-1: reserved. Write as 0, value read don't have meaning, R.
/// - 0: ITIP0, Primary Output. Writes specify the value to be driven on UARTTXD, R/W.
pub const ITOP: usize = UART_START + 0x88;
/// Test Data register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10-0: TDR10_0. When ITCRI1 is set to 1, data read an write directly from the FIFOs, R/W.
pub const TDR: usize = UART_START + 0x8C;
pub struct UartMemoryMap {
/// Data Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R/W.
/// - 11: OE, Overrun Error. Set to 1 if data received with FIFO full, R/W.
/// - 10: BE, Break Error. Set to 1 if a break condition was detected, R/W.
/// - 9: PE, Parity Error. Set to 1 when the parity don't match data, R/W.
/// - 8: FE, Framing Error. Set to 1 when character don't have valid stop bit, R/W.
/// - 7-0: DATA, Data character. R/W.
pub dr: Field,
/// OE, Overrun Error. Set to 1 if data received with FIFO full, R/W.
///
/// Field located inside the Data Register [`dr`].
pub dr_oe: Field,
/// BE, Break Error. Set to 1 if a break condition was detected, R/W.
///
/// Field located inside the Data Register [`dr`].
pub dr_be: Field,
/// PE, Parity Error. Set to 1 when the parity don't match data, R/W.
///
/// Field located inside the Data Register [`dr`].
pub dr_pe: Field,
/// FE, Framing Error. Set to 1 when character don't have valid stop bit, R/W.
///
/// Field located inside the Data Register [`dr`].
pub dr_fe: Field,
/// DATA, Data character. R/W.
///
/// Field located inside the Data Register [`dr`].
pub dr_data: Field,
/// Receive Status Register/Error Clear Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R/W.
/// - 3: OE, Overrun Error. Set to 1 if data received with FIFO full, R/W.
/// - 2: BE, Break Error. Set to 1 if a break condition was detected, R/W.
/// - 1: PE, Parity Error. Set to 1 when the parity don't match data, R/W.
/// - 0: FE, Framing Error. Set to 1 when characteur don't have valid stop bit, R/W.
pub rsrecr: Field,
/// OE, Overrun Error. Set to 1 if data received with FIFO full, R/W.
///
/// Field located inside the Receive Status Register/Error Clear Register [`rsrecr`].
pub rsrecr_oe: Field,
/// BE, Break Error. Set to 1 if a break condition was detected, R/W.
///
/// Field located inside the Receive Status Register/Error Clear Register [`rsrecr`].
pub rsrecr_be: Field,
/// PE, Parity Error. Set to 1 when the parity don't match data, R/W.
///
/// Field located inside the Receive Status Register/Error Clear Register [`rsrecr`].
pub rsrecr_pe: Field,
/// FE, Framing Error. Set to 1 when characteur don't have valid stop bit, R/W.
///
/// Field located inside the Receive Status Register/Error Clear Register [`rsrecr`].
pub rsrecr_fe: Field,
/// Flag Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-9: reserved. Write as 0, value read don't have meaning, R/W.
/// - 8: RI, unsuported. Write as 0, value read don't have meaning, R/W.
/// - 7: TXFE, Transmit FIFO Empty. If FIFO disabled, set when tx holding register empty.
/// If FIFO enabled, set when tx FIFP is empty. R/W.
/// - 6: RXFF, Receive FIFO Full. If FIFO disabled, set when rx holding register is full.
/// If FIFO enabled, set when rx FIFO is full. R/W.
/// - 5: TXFF, Transmit FIFO Full. If FIFO disabled, set when tx holding register full.
/// If FIFO enabled, set when tx FIFP is full. R/W.
/// - 4: RXFE, Receive FIFO Empty. If FIFO disabled, set when rx holding register is empty.
/// If FIFO enabled, set when rx FIFO is empty. R/W.
/// - 3: BUSY. Is set, UART is busy transmitting data. R/W.
/// - 2: DCD, unsuported. Write as 0, value read don't have meaning, R/W.
/// - 1: DSR, unsuported. Write as 0, value read don't have meaning, R/W.
/// - 0: CTS, Clear To Send.
pub fr: Field,
/// RI, unsuported. Write as 0, value read don't have meaning, R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_ri: Field,
/// TXFE, Transmit FIFO Empty. If FIFO disabled, set when tx holding register empty.
/// If FIFO enabled, set when tx FIFP is empty. R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_txfe: Field,
/// RXFF, Receive FIFO Full. If FIFO disabled, set when rx holding register is full.
/// If FIFO enabled, set when rx FIFO is full. R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_rxff: Field,
/// TXFF, Transmit FIFO Full. If FIFO disabled, set when tx holding register full.
/// If FIFO enabled, set when tx FIFP is full. R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_txff: Field,
/// RXFE, Receive FIFO Empty. If FIFO disabled, set when rx holding register is empty.
/// If FIFO enabled, set when rx FIFO is empty. R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_rxfe: Field,
/// BUSY. Is set, UART is busy transmitting data. R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_busy: Field,
/// DCD, unsuported. Write as 0, value read don't have meaning, R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_dcd: Field,
/// DSR, unsuported. Write as 0, value read don't have meaning, R/W.
///
/// Field located inside the Flag Register [`fr`].
pub fr_dsr: Field,
/// CTS, Clear To Send.
///
/// Field located inside the Flag Register [`fr`].
pub fr_cts: Field,
/// Not in use. 32 bits long.
pub ilpr: Field,
/// Integer Baud rate divisor, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-16: reserved. Write as 0, value read don't have meaning, R/W.
/// - 15-0: IBRD. The integer baud rate divisor, R/W.
pub ibrd: Field,
/// Fractional Baud rate divisor, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-6: reserved. Write as 0, value read don't have meaning, R/W.
/// - 5-0: FBRD. The fractional baud rate divisor, R/W.
pub fbrd: Field,
/// Line Constrol Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-8: reserved. Write as 0, value read don't have meaning, R/W.
/// - 7: SPS, Stick Parity Select. 0: the stick parity is disabled, 1: either
/// depending on EPS (Event Parity Select), R/W.
/// - 6-5: WLEN: World lenght. Number of data bits transmitted by frame (0b00 -> 5b, 0b11 ->
/// 8b), R/W.
/// - 4: FEN, Enable FIFOs. 0: FIFOs disabled, 1: FIFO buffers are enables, R/W.
/// - 3: STP2, 2 Stop bit select. 1: 2 stop bits are transmitted at the end of the frame
/// (rx logic is not affected), R/W.
/// - 2: EPS, Event Parity Select. 0: odd parity, check for odd number of 1 in data+parity
/// bits, 1: event parity, check for even number of 1 in data+parity. No effect when
/// PEN disable parity check. R/W.
/// - 1: PEN, Parity Enable. 0: Don't add parity bit and don't check parity, 1: add parity bit
/// and check for parity, R/W.
/// - 0: BRK: Send break. If set, send continuous low level to TXD after the current char, R/W.
pub lcrh: Field,
/// SPS, Stick Parity Select. 0: the stick parity is disabled, 1: either
/// depending on [EPS](lcrh_eps) (Event Parity Select), R/W.
///
/// Field located inside the Line Constrol Register [`lcrh`].
pub lcrh_sps: Field,
/// WLEN: World lenght. Number of data bits transmitted by frame (0b00 -> 5b, 0b11 ->
/// 8b), R/W.
///
/// Field located inside the Line Constrol Register [`lcrh`].
pub lcrh_wlen: Field,
/// FEN, Enable FIFOs. 0: FIFOs disabled, 1: FIFO buffers are enables, R/W.
///
/// Field located inside the Line Constrol Register [`lcrh`].
pub lcrh_fen: Field,
/// STP2, 2 Stop bit select. 1: 2 stop bits are transmitted at the end of the frame
/// (rx logic is not affected), R/W.
///
/// Field located inside the Line Constrol Register [`lcrh`].
pub lcrh_stp2: Field,
/// EPS, Event Parity Select. 0: odd parity, check for odd number of 1 in data+parity
/// bits, 1: event parity, check for even number of 1 in data+parity. No effect when
/// PEN disable parity check. R/W.
///
/// Field located inside the Line Constrol Register [`lcrh`].
pub lcrh_eps: Field,
/// PEN, Parity Enable. 0: Don't add parity bit and don't check parity, 1: add parity bit
/// and check for parity, R/W.
///
/// Field located inside the Line Constrol Register [`lcrh`].
pub lcrh_pen: Field,
/// BRK: Send break. If set, send continuous low level to TXD after the current char, R/W.
///
/// Field located inside the Line Constrol Register [`lcrh`].
pub lcrh_brk: Field,
/// Control Register, 32 bits long.
///
/// # Warning
///
/// To program the CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
///
/// # Bits distribution:
///
/// - 31-16: reserved. Write as 0, value read don't have meaning, R/W.
/// - 15: CTSEN, CTS hardware flow control enable. If set, data is only transmitted when
/// nUARTCTS is asserted, R/W.
/// - 14: RTSEN, RST hardware flow control enable. If set, data is only requested when there
/// is space in the receive FIFO, R/W.
/// - 13: OUT2, unsuported, Write as 0, value read don't have meaning, R.
/// - 12: OUT1, unsuported, Write as 0, value read don't have meaning, R.
/// - 11: RTS, Request To Send. When set to 1, nUARTRTS is low, R/W.
/// - 10: DTR, unsuported, Write as 0, value read don't have meaning, R.
/// - 9: RXE, Receive enable. If set, (and if UARTEN is set), the uart can read data, R/W.
/// - 8: TXE, Transmit enable. If set, (and if UARTEN is set), the uart can send data, R/W.
/// - 7: LBE, LoopBack Enable. If set, UARTTXD is fed through to the UARTRXD path, R/W.
/// - 6-3: reserved. Write as 0, value read don't have meaning, R/W.
/// - 2: SIRLP, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: SIREN, unsuported, Write as 0, value read don't have meaning, R.
/// - 0: UARTEN, UART enable. If set, the UART is enable, R/W.
pub cr: Field,
/// CTSEN, CTS hardware flow control enable. If set, data is only transmitted when
/// nUARTCTS is asserted, R/W.
///
/// Field located inside the Control Register [`cr`].
///
/// # Warning:
///
/// According to the doc, the following operation must be performed to program CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
pub cr_ctsen: Field,
/// RTSEN, RST hardware flow control enable. If set, data is only requested when there
/// is space in the receive FIFO, R/W.
///
/// Field located inside the Control Register [`cr`].
///
/// # Warning:
///
/// According to the doc, the following operation must be performed to program CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
pub cr_rtsen: Field,
/// OUT2, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_out2: Field,
/// OUT1, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_out1: Field,
/// RTS, Request To Send. When set to 1, nUARTRTS is low, R/W.
///
/// Field located inside the Control Register [`cr`].
///
/// # Warning:
///
/// According to the doc, the following operation must be performed to program CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
pub cr_rts: Field,
/// DTR, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_dtr: Field,
/// RXE, Receive enable. If set, (and if UARTEN is set), the uart can read data, R/W.
///
/// Field located inside the Control Register [`cr`].
///
/// # Warning:
///
/// According to the doc, the following operation must be performed to program CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
/// DTR, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_rxe: Field,
/// TXE, Transmit enable. If set, (and if UARTEN is set), the uart can send data, R/W.
///
/// Field located inside the Control Register [`cr`].
///
/// # Warning:
///
/// According to the doc, the following operation must be performed to program CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
/// DTR, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_txe: Field,
/// LBE, LoopBack Enable. If set, UARTTXD is fed through to the UARTRXD path, R/W.
///
/// Field located inside the Control Register [`cr`].
///
/// # Warning:
///
/// According to the doc, the following operation must be performed to program CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
/// DTR, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_lbe: Field,
/// SIRLP, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_sirlp: Field,
/// SIREN, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_siren: Field,
/// UARTEN, UART enable. If set, the UART is enable, R/W.
///
/// Field located inside the Control Register [`cr`].
///
/// # Warning:
///
/// According to the doc, the following operation must be performed to program CR:
///
/// - 1) Disable UART
/// - 2) Wait for the end of tx/rx of the current char
/// - 3) Flush the transmit FIFO by setting `FEN` to 0 in [`LCRH`]
/// - 4) Reprogram `CR`.
/// - 5) Enable UART
/// DTR, unsuported, Write as 0, value read don't have meaning, R.
///
/// Field located inside the Control Register [`cr`].
pub cr_uarten: Field,
// TODO: Finish detailling the registers
/// Interrupt FIFO Level Select register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R/W.
/// - 11-9: RXIFPSEL, unsuported, Write as 0, value read don't have meaning, R.
/// - 8-6: TXIFPSEL, unsuported, Write as 0, value read don't have meaning, R.
/// - 5-3: RXIFLSEL, Receive Interrupt FIFO Level Select. The level from which the
/// reveive interrupt is send:
/// - `0b000`: Send when FIFO becom 1/8 full
/// - `0b001`: Send when FIFO becom 1/4 full
/// - `0b010`: Send when FIFO becom 1/2 full
/// - `0b011`: Send when FIFO becom 3/4 full
/// - `0b100`: Send when FIFO becom 7/7 full
/// - Other values are reserved.
/// R/W.
/// - 2-0: TXIFLSEL, Transmit Interrupt FIFO Level Select. The level from which the
/// transmit interrupt is send:
/// - `0b000`: Send when FIFO becom 1/8 full
/// - `0b001`: Send when FIFO becom 1/4 full
/// - `0b010`: Send when FIFO becom 1/2 full
/// - `0b011`: Send when FIFO becom 3/4 full
/// - `0b100`: Send when FIFO becom 7/7 full
/// - Other values are reserved.
/// R/W.
pub ifls: Field,
/// Interupt Mask Set Clear register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R/W.
/// - 10: OEIM, Overrun Error Interrupt Mask. Value of the mask for OE Interrupt, R/W.
/// - 9: BEIM, Break Error Interrupt Mask. Value of the mask for BE Interrupt, R/W.
/// - 8: PEIM, Parity Error Interrupt Mask. Value of the mask for PE Interrupt, R/W.
/// - 7: FEIM, Framing Error Interrupt Mask. Value of the mask for FE Interrupt, R/W.
/// - 6: RT Interrupt, Receive Timeout Interrupt Mask. Value of the mask for RTIM, R/W.
/// - 5: TXIM, Transmit Interrupt Mask. Value of the mask for TX Interrupt, R/W.
/// - 4: RXIM, Receive Interrupt Mask. Value of the mask for RX Interrupt, R/W.
/// - 3: DSRMIM, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMIM, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMIM, nUARTCTS Modem Interrupt Mask. Value of the mask for CTS Interrupt, R/W.
/// - 0: RIMIM, unsuported, Write as 0, value read don't have meaning, R.
pub imsc: Field,
/// Raw Interupt Status register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10: OERIS, Overrun Error Raw Interrupt Status. Raw interrupt state of the OE Interrupt, R.
/// - 9: BERIS, Break Error Raw Interrupt Status. Raw interrupt state of the BE Interrupt, R.
/// - 8: PERIS, Parity Error Raw Interrupt Status. Raw interrupt state of the PE Interrupt, R.
/// - 7: FERIS, Framing Error Raw Interrupt Status. Raw interrupt state of the FE Interrupt, R.
/// - 6: RT Interrupt, Receive Timeout Raw Interrupt Status. Raw interrupt state of the RTRIS, R.
/// - 5: TXRIS, Transmit Raw Interrupt Status. Raw interrupt state of the TX Interrupt, R.
/// - 4: RXRIS, Receive Raw Interrupt Status. Raw interrupt state of the RX Interrupt, R.
/// - 3: DSRMRIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMRIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMRIS, nUARTCTS Modem Raw Interrupt Status. Raw interrupt state of the CTS Interrupt, R.
/// - 0: RRISIM, unsuported, Write as 0, value read don't have meaning, R.
pub ris: Field,
/// Masked Interupt Status register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10: OEMIS, Overrun Error Masked Interrupt Status. Masked interrupt state of the OE Interrupt, R.
/// - 9: BEMIS, Break Error Masked Interrupt Status. Masked interrupt state of the BE Interrupt, R.
/// - 8: PEMIS, Parity Error Masked Interrupt Status. Masked interrupt state of the PE Interrupt, R.
/// - 7: FEMIS, Framing Error Masked Interrupt Status. Masked interrupt state of the FE Interrupt, R.
/// - 6: RT Interrupt, Receive Timeout Masked Interrupt Status. Masked interrupt state of the RTMIS, R.
/// - 5: TXMIS, Transmit Masked Interrupt Status. Masked interrupt state of the TX Interrupt, R.
/// - 4: RXMIS, Receive Masked Interrupt Status. Masked interrupt state of the RX Interrupt, R.
/// - 3: DSRMMIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMMIS, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMMIS, nUARTCTS Modem Masked Interrupt Status. Masked interrupt state of the CTS Interrupt, R.
/// - 0: RMISIM, unsuported, Write as 0, value read don't have meaning, R.
pub mis: Field,
/// Interupt Clear Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10: OEIC, Overrun Error Interrupt Clear. Clear the OE Interrupt, R.
/// - 9: BEIC, Break Error Interrupt Clear. Clear the BE Interrupt, R.
/// - 8: PEIC, Parity Error Interrupt Clear. Clear the PE Interrupt, R.
/// - 7: FEIC, Framing Error Interrupt Clear. Clear the FE Interrupt, R.
/// - 6: RT Interrupt, Receive Timeout Interrupt Clear. Clear the RTIC, R.
/// - 5: TXIC, Transmit Interrupt Clear. Clear the TX Interrupt, R.
/// - 4: RXIC, Receive Interrupt Clear. Clear the RX Interrupt, R.
/// - 3: DSRMIC, unsuported, Write as 0, value read don't have meaning, R.
/// - 2: DCDMIC, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: CTSMIC, nUARTCTS Modem Interrupt Clear. Clear the CTS Interrupt, R.
/// - 0: RICIM, unsuported, Write as 0, value read don't have meaning, R.
pub icr: Field,
/// DMA Control Register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-3: reserved. Write as 0, value read don't have meaning, R.
/// - 2: DMAONERR, unsuported, Write as 0, value read don't have meaning, R.
/// - 1: TXDMAE, unsuported, Write as 0, value read don't have meaning, R.
/// - 0: RXDMAE, unsuported, Write as 0, value read don't have meaning, R.
pub dmacr: Field,
/// Test Control register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-2: reserved. Write as 0, value read don't have meaning, R.
/// - 1: ITCR1, Test FIFO enable. If set, read/write directly to the FIFOs with TDR10_0, R/W.
/// - 0: ITCR0, Integration Test Enable. If set, the UART is placed in intergration test mode,
/// R/W.
pub itcr: Field,
/// Integration Test Input register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-4: reserved. Write as 0, value read don't have meaning, R.
/// - 3: ITIP3. Reads returns the value of nUARTCTS, R/W.
/// - 2-1: reserved. Write as 0, value read don't have meaning, R.
/// - 0: ITIP0. Reads the value of UARTRXD, R/W.
pub itip: Field,
/// Integration Test Output register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-12: reserved. Write as 0, value read don't have meaning, R.
/// - 11: ITOP11, Intra-chip Output. Writes set the value to be driven on UARTLSINTR, Reads
/// returns the value of UARTLSINTR at the output of the test multiplexor, R/W.
/// - 10: ITOP10, Intra-chip Output. Writes set the value to be driven on UARTRXINTR, Reads
/// returns the value of UARTRXINTR at the output of the test multiplexor, R/W.
/// - 9: ITOP9, Intra-chip Output. Writes set the value to be driven on UARTTXINTR, Reads
/// returns the value of UARTTXINTR at the output of the test multiplexor, R/W.
/// - 8: ITOP8, Intra-chip Output. Writes set the value to be driven on UARTRTINTR, Reads
/// returns the value of UARTRTINTR at the output of the test multiplexor, R/W.
/// - 7: ITOP7, Intra-chip Output. Writes set the value to be driven on UARTEINTR, Reads
/// returns the value of UARTEINTR at the output of the test multiplexor, R/W.
/// - 6: ITOP6, Intra-chip Output. Writes set the value to be driven on UARTINTR, Reads
/// returns the value of UARTINTR at the output of the test multiplexor, R/W.
/// - 5-4: reserved. Write as 0, value read don't have meaning, R.
/// - 3: ITIP3: Primary Output. Writes specify the value on nUARTRTS, R/W.
/// - 2-1: reserved. Write as 0, value read don't have meaning, R.
/// - 0: ITIP0, Primary Output. Writes specify the value to be driven on UARTTXD, R/W.
pub itop: Field,
/// Test Data register, 32 bits long.
///
/// # Bits distribution:
///
/// - 31-11: reserved. Write as 0, value read don't have meaning, R.
/// - 10-0: TDR10_0. When ITCRI1 is set to 1, data read an write directly from the FIFOs, R/W.
pub tdr: Field,
}
impl UartMemoryMap {
/// Contructor for a [`UartMemoryMap`] starting at `start_address`.
const fn new(start_address: usize) -> Self {
Self {
// TODO: set unsuported field to size 0?
dr: Field::new(start_address + 0x00, 0, 32),
dr_oe: Field::new(start_address + 0x00, 11, 1),
dr_be: Field::new(start_address + 0x00, 10, 1),
dr_pe: Field::new(start_address + 0x00, 9, 1),
dr_fe: Field::new(start_address + 0x00, 8, 1),
dr_data: Field::new(start_address + 0x00, 0, 8),
rsrecr: Field::new(start_address + 0x04, 0, 32),
rsrecr_oe: Field::new(start_address + 0x04, 3, 1),
rsrecr_be: Field::new(start_address + 0x04, 2, 1),
rsrecr_pe: Field::new(start_address + 0x04, 1, 1),
rsrecr_fe: Field::new(start_address + 0x04, 0, 1),
fr: Field::new(start_address + 0x18, 0, 32),
fr_ri: Field::new(start_address + 0x18, 8, 1),
fr_txfe: Field::new(start_address + 0x18, 7, 1),
fr_rxff: Field::new(start_address + 0x18, 6, 1),
fr_txff: Field::new(start_address + 0x18, 5, 1),
fr_rxfe: Field::new(start_address + 0x18, 4, 1),
fr_busy: Field::new(start_address + 0x18, 3, 1),
fr_dcd: Field::new(start_address + 0x18, 2, 1),
fr_dsr: Field::new(start_address + 0x18, 1, 1),
fr_cts: Field::new(start_address + 0x18, 0, 1),
ilpr: Field::new(start_address + 0x20, 0, 32),
ibrd: Field::new(start_address + 0x24, 0, 16),
fbrd: Field::new(start_address + 0x28, 0, 6),
lcrh: Field::new(start_address + 0x2C, 0, 32),
lcrh_sps: Field::new(start_address + 0x2C, 7, 1),
lcrh_wlen: Field::new(start_address + 0x2C, 5, 2),
lcrh_fen: Field::new(start_address + 0x2C, 4, 1),
lcrh_stp2: Field::new(start_address + 0x2C, 3, 1),
lcrh_eps: Field::new(start_address + 0x2C, 2, 1),
lcrh_pen: Field::new(start_address + 0x2C, 1, 1),
lcrh_brk: Field::new(start_address + 0x2C, 0, 1),
cr: Field::new(start_address + 0x30, 0, 32),
cr_ctsen: Field::new(start_address + 0x30, 15, 1),
cr_rtsen: Field::new(start_address + 0x30, 14, 1),
cr_out2: Field::new(start_address + 0x30, 13, 1),
cr_out1: Field::new(start_address + 0x30, 12, 1),
cr_rts: Field::new(start_address + 0x30, 11, 1),
cr_dtr: Field::new(start_address + 0x30, 10, 1),
cr_rxe: Field::new(start_address + 0x30, 9, 1),
cr_txe: Field::new(start_address + 0x30, 8, 1),
cr_lbe: Field::new(start_address + 0x30, 7, 1),
cr_sirlp: Field::new(start_address + 0x30, 2, 1),
cr_siren: Field::new(start_address + 0x30, 1, 1),
cr_uarten: Field::new(start_address + 0x30, 0, 1),
ifls: Field::new(start_address + 0x34, 0, 32),
imsc: Field::new(start_address + 0x38, 0, 32),
ris: Field::new(start_address + 0x3C, 0, 32),
mis: Field::new(start_address + 0x40, 0, 32),
icr: Field::new(start_address + 0x44, 0, 32),
dmacr: Field::new(start_address + 0x48, 0, 32),
itcr: Field::new(start_address + 0x80, 0, 32),
itip: Field::new(start_address + 0x84, 0, 32),
itop: Field::new(start_address + 0x88, 0, 32),
tdr: Field::new(start_address + 0x8C, 0, 32),
}
}
}
pub const UART: UartMemoryMap = UartMemoryMap::new(UART_START);
}

@ -2,33 +2,22 @@
use core::arch::asm;
use core::fmt;
use core::ptr::{read_volatile, write_volatile};
use crate::utils::field::Field;
use crate::traits::console::{Write, Console};
use super::memory_map::uart::*;
use super::memory_map::uart as mm;
pub struct Uart {
pub struct Uart<'a> {
initialized: bool,
memory_map: &'a mm::UartMemoryMap,
}
const TMP_UARTEN: Field = Field::new(CR, 0, 1);
const TMP_TXE: Field = Field::new(CR, 8, 1);
const TMP_BUSY: Field = Field::new(FR, 3, 1);
const TMP_TXFF: Field = Field::new(FR, 5, 1);
const TMP_FEN: Field = Field::new(LCRH, 4, 1);
const TMP_WLEN: Field = Field::new(LCRH, 5, 2);
const TMP_IBRD: Field = Field::new(IBRD, 0, 16);
const TMP_FBRD: Field = Field::new(FBRD, 0, 6);
const TMP_DATA: Field = Field::new(DR, 0, 8);
impl Uart {
impl<'a> Uart<'a> {
// TODO: not sure this should be public outside of bsp.
/// Constructor for [`Uart`].
pub const fn new() -> Self {
Uart { initialized: false }
pub const fn new(memory_map: &'a mm::UartMemoryMap) -> Self {
Uart { initialized: false, memory_map }
}
/// Initialise the UART.
@ -38,17 +27,13 @@ impl Uart {
self.flush();
// Stop UART
let mut cr_val = unsafe { read_volatile(TMP_UARTEN.get_address() as *mut u32) };
cr_val &= !TMP_UARTEN.get_mask();
unsafe { write_volatile(TMP_UARTEN.get_address() as *mut u32, cr_val); }
self.memory_map.cr_uarten.read_and_write(0);
// Flush the FIFOs
let mut lcrh_val = unsafe { read_volatile(TMP_FEN.get_address() as *mut u32) };
lcrh_val &= !TMP_FEN.get_mask();
unsafe { write_volatile(TMP_FEN.get_address() as *mut u32, lcrh_val); }
self.memory_map.lcrh_fen.read_and_write(0);
// Clear all interrupt
unsafe { write_volatile(ICR as *mut u32, 0); }
self.memory_map.icr.write_without_read(0);
// Config UART
// 8N1 115_200 bauds.
@ -56,42 +41,37 @@ impl Uart {
// divbaud = freq/16/baudrate = 48_000_000 / 16 / 115_200 = 26.041666666666668
// => IBRD = 26
// => FBRD = round(0.041666666666668 * 64) = 3 // TODO: why 64?
unsafe { write_volatile(TMP_IBRD.get_address() as *mut u32, 26 & TMP_IBRD.get_mask()); }
unsafe { write_volatile(TMP_FBRD.get_address() as *mut u32, 3 & TMP_FBRD.get_mask()); }
self.memory_map.ibrd.write_without_read(26);
self.memory_map.fbrd.write_without_read(3);
lcrh_val = 0;
// Set word len to 8
lcrh_val |= 0b11 << TMP_WLEN.get_offset();
let lcrh_val = self.memory_map.lcrh_wlen.read_and_write_to_u32(0b11, 0);
// Reenable the FIFOs
lcrh_val |= TMP_FEN.get_mask();
unsafe { write_volatile(LCRH as *mut u32, lcrh_val); }
let lcrh_val = self.memory_map.lcrh_fen.read_and_write_to_u32(1, lcrh_val);
self.memory_map.lcrh.write_without_read(lcrh_val);
let mut cr_val = 0;
cr_val |= TMP_TXE.get_mask(); // enable TX
unsafe { write_volatile(TMP_TXE.get_address() as *mut u32, cr_val); }
let cr_val = self.memory_map.cr_txe.read_and_write_to_u32(1, 0);
// TODO: let cr_val = self.memory_map.cr_rxe.read_and_write_to_u32(1, 0); to enable read
self.memory_map.cr.write_without_read(cr_val);
// Start the UART
cr_val |= TMP_UARTEN.get_mask();
unsafe { write_volatile(TMP_UARTEN.get_address() as *mut u32, cr_val); }
self.memory_map.cr_uarten.read_and_write(1);
self.initialized = true;
}
/// Test if the UART is busy.
fn is_busy(&self) -> bool {
let fr_val = unsafe { read_volatile(TMP_BUSY.get_address() as *mut u32) };
(fr_val & TMP_BUSY.get_mask()) != 0
self.memory_map.fr_busy.read() != 0
}
/// Test if the the TX FIFO is full.
fn is_tx_full(&self) -> bool {
let fr_val = unsafe { read_volatile(TMP_TXFF.get_address() as *mut u32) };
(fr_val & TMP_TXFF.get_mask()) != 0
self.memory_map.fr_txff.read() != 0
}
}
// Allow the use of uart for fmt::Write::write_fmt.
impl fmt::Write for Uart {
impl fmt::Write for Uart<'_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
for c in s.chars() {
if c == '\n' {
@ -104,7 +84,7 @@ impl fmt::Write for Uart {
}
// TODO: add sync
impl Write for Uart {
impl Write for Uart<'_> {
fn write_char(&self, c: char) {
if !self.initialized {
//panic!("Cannot write to a non initialized UART");
@ -114,12 +94,12 @@ impl Write for Uart {
let _ = gpio::set_pin_output_state(20, gpio::PinOutputState::High);
unsafe { asm!("nop") };
}
unsafe { write_volatile(TMP_DATA.get_address() as *mut u32, c as u32) };
self.memory_map.dr_data.write_without_read(c as u32);
}
fn write_fmt(&self, args: fmt::Arguments) -> fmt::Result {
// TODO: use syncronisation here
let mut new_uart = Uart { initialized: self.initialized };
let mut new_uart = Uart { initialized: self.initialized, memory_map: self.memory_map};
fmt::Write::write_fmt(&mut new_uart, args)
}
@ -130,12 +110,12 @@ impl Write for Uart {
}
}
impl Console for Uart {}
impl Console for Uart<'_> {}
static UART: Uart = Uart { initialized: true }; // TODO: use sync
static UART: Uart = Uart { initialized: true, memory_map: &mm::UART }; // TODO: use sync
pub fn init() {
let mut uart = Uart::new();
let mut uart = Uart::new(&mm::UART);
uart.init();
}

@ -5,8 +5,8 @@
//! but it's a project for discovering rust on embedded, so its architecture is less generic and
//! I'm trying to reuse knowledge from Telecom-Paris SE203 class as much as I can.
#![no_main]
#![no_std]
#![cfg_attr(not(test), no_main)]
#![cfg_attr(not(test), no_std)]
#![feature(format_args_nl)]
#![feature(panic_info_message)]
@ -16,19 +16,26 @@ mod traits;
mod bsp;
mod utils;
#[cfg(not(test))]
mod panic;
#[cfg(not(test))]
mod print;
#[cfg(not(test))]
use core::arch::global_asm;
#[cfg(not(test))]
use core::arch::asm;
// TODO: handle this with features
//use crate::bsp::qemu::console::console;
#[cfg(not(test))]
use crate::bsp::rpi3::uart::console;
#[cfg(not(test))]
use crate::bsp::rpi3::gpio;
// TODO: move this to BSP
/// Pause the core with a infinit loop
#[cfg(not(test))]
#[inline(always)]
pub fn wait_forever() -> ! {
loop {
@ -37,9 +44,11 @@ pub fn wait_forever() -> ! {
}
// TODO: move this to BSP
#[cfg(not(test))]
global_asm!(include_str!("boot.s"));
/// Start the rust part of the kernel
#[cfg(not(test))]
#[no_mangle]
pub unsafe fn _start_rust() -> ! {
@ -85,3 +94,6 @@ pub unsafe fn _start_rust() -> ! {
panic!("Paniccccccc")
*/
}
#[cfg(test)]
fn main() {}

@ -1,5 +1,7 @@
//! Implement the Field structure.
use core::ptr::{read_volatile, write_volatile};
/// Structure representing the location of a register.
/// This structure does not provide any kind of safety, it
/// is only descriptif.
@ -11,6 +13,8 @@
/// The constructor of the is class ensure that the field is
/// always inside the `u32` at `address`, and that `address`
/// is alligned.
///
/// TODO: Mark write method as unsafe?
pub struct Field {
/// The address of the discribed field.
address: usize,
@ -23,7 +27,6 @@ pub struct Field {
mask: u32
}
// TODO: test
impl Field {
/// Constructor for a Field.
/// The field is defined by the `size` bits at `offset` bits after
@ -65,7 +68,6 @@ impl Field {
}
/// Return the offset of the field in relation to the address, in bits.
#[allow(dead_code)]
pub const fn get_offset(&self) -> usize {
self.offset
}
@ -80,4 +82,154 @@ impl Field {
pub const fn get_mask(&self) -> u32 {
self.mask
}
/// Set the value of the field in the provided u32.
#[inline]
pub fn read_and_write_to_u32(&self, val: u32, register: u32) -> u32 {
assert_eq!(val & !(self.mask >> self.offset), 0, "Value greater than the field");
register & !self.mask | (val << self.offset)
}
/// Get the value of the field from the provided u32.
#[inline]
pub fn read_from_u32(&self, register: u32) -> u32 {
(register & self.mask) >> self.offset
}
/// Write the value in memory.
pub fn read_and_write(&self, val: u32) {
let register = unsafe { read_volatile(self.address as *mut u32) };
let register = self.read_and_write_to_u32(val, register);
unsafe { write_volatile(self.address as *mut u32, register) };
}
/// Write the value in memory but override every other value of the
/// u32 (replace them by 0s).
pub fn write_without_read(&self, val: u32) {
let register = self.read_and_write_to_u32(val, 0);
unsafe { write_volatile(self.address as *mut u32, register) };
}
/// Read the value from memory.
pub fn read(&self) -> u32 {
let register = unsafe { read_volatile(self.address as *mut u32) };
self.read_from_u32(register)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_get_address() {
// Test when the address is alligned
assert_eq!(
Field::new(0x1234_5678, 0, 1).get_address(),
0x1234_5678,
);
}
#[test]
fn test_get_offset() {
assert_eq!(
Field::new(0x1234_5678, 18, 1).get_offset(),
18,
);
}
#[test]
fn test_get_size() {
assert_eq!(
Field::new(0x1234_5678, 18, 1).get_size(),
1,
);
}
#[test]
fn test_alignment_enforcement() {
let field = Field::new(0x1111_1110, 0, 1);
assert_eq!(field.get_address(), 0x1111_1110);
assert_eq!(field.get_offset(), 0);
let field = Field::new(0x1111_1111, 0, 1);
assert_eq!(field.get_address(), 0x1111_1110);
assert_eq!(field.get_offset(), 8);
let field = Field::new(0x1111_1112, 0, 1);
assert_eq!(field.get_address(), 0x1111_1110);
assert_eq!(field.get_offset(), 16);
let field = Field::new(0x1111_1113, 0, 1);
assert_eq!(field.get_address(), 0x1111_1110);
assert_eq!(field.get_offset(), 24);
}
#[test]
fn test_closeness_enforcement() {
let field = Field::new(0x1111_1110, 32, 1);
assert_eq!(field.get_address(), 0x1111_1114);
assert_eq!(field.get_offset(), 0);
let field = Field::new(0x1111_1111, 32, 1);
assert_eq!(field.get_address(), 0x1111_1114);
assert_eq!(field.get_offset(), 8);
let field = Field::new(0x1111_1112, 32+16, 1);
assert_eq!(field.get_address(), 0x1111_1118);
assert_eq!(field.get_offset(), 0);
}
#[test]
#[should_panic]
fn test_prevent_overlaps() {
let _ = Field::new(0, 24, 16);
}
#[test]
fn test_get_mask() {
assert_eq!(
Field::new(0, 0, 1).get_mask(),
0b0000_0001,
);
assert_eq!(
Field::new(0, 0, 3).get_mask(),
0b0000_0111,
);
assert_eq!(
Field::new(0, 4, 1).get_mask(),
0b0001_0000,
);
assert_eq!(
Field::new(0, 4, 3).get_mask(),
0b0111_0000,
);
}
#[test]
fn test_read_and_write_to_u32() {
let field = Field::new(0, 3, 4);
let val = 0b0101_0101;
assert_eq!(
field.read_and_write_to_u32(0b0101, val),
0b0010_1101,
);
}
#[test]
#[should_panic]
fn test_read_and_write_to_u32_too_big() {
let field = Field::new(0, 0, 3);
let _ = field.read_and_write_to_u32(0b1111, 0);
}
#[test]
fn test_read_from_u32() {
let field = Field::new(0, 3, 4);
let val = 0b1100_1111;
assert_eq!(
field.read_from_u32(val),
0b1001,
);
}
}

Loading…
Cancel
Save