implement UartMemoryMap
This commit is contained in:
parent
67d443910c
commit
a01b2dff60
2 changed files with 644 additions and 295 deletions
|
@ -262,6 +262,7 @@ pub const UART_START: usize = START_PHYSICAL_ADDRESS + UART_OFFSET;
|
|||
pub mod uart {
|
||||
use super::*;
|
||||
|
||||
pub struct UartMemoryMap {
|
||||
/// Data Register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -272,7 +273,34 @@ pub mod uart {
|
|||
/// - 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;
|
||||
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:
|
||||
|
@ -282,8 +310,29 @@ pub mod uart {
|
|||
/// - 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.
|
||||
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:
|
||||
///
|
||||
|
@ -301,24 +350,77 @@ pub mod uart {
|
|||
/// - 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;
|
||||
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 const ILPR: usize = UART_START + 0x20;
|
||||
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 const IBRD: usize = UART_START + 0x24;
|
||||
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 const FBRD: usize = UART_START + 0x28;
|
||||
/// Line Constrol register, 32 bits long.
|
||||
pub fbrd: Field,
|
||||
|
||||
/// Line Constrol Register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
///
|
||||
|
@ -336,8 +438,50 @@ pub mod uart {
|
|||
/// - 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.
|
||||
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
|
||||
///
|
||||
|
@ -367,8 +511,155 @@ pub mod uart {
|
|||
/// - 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.
|
||||
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:
|
||||
///
|
||||
|
@ -393,7 +684,7 @@ pub mod uart {
|
|||
/// - `0b100`: Send when FIFO becom 7/7 full
|
||||
/// - Other values are reserved.
|
||||
/// R/W.
|
||||
pub const IFLS: usize = UART_START + 0x34;
|
||||
pub ifls: Field,
|
||||
/// Interupt Mask Set Clear register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -410,7 +701,7 @@ pub mod uart {
|
|||
/// - 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;
|
||||
pub imsc: Field,
|
||||
/// Raw Interupt Status register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -427,7 +718,7 @@ pub mod uart {
|
|||
/// - 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;
|
||||
pub ris: Field,
|
||||
/// Masked Interupt Status register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -444,7 +735,7 @@ pub mod uart {
|
|||
/// - 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;
|
||||
pub mis: Field,
|
||||
/// Interupt Clear Register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -461,7 +752,7 @@ pub mod uart {
|
|||
/// - 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;
|
||||
pub icr: Field,
|
||||
/// DMA Control Register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -470,7 +761,7 @@ pub mod uart {
|
|||
/// - 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;
|
||||
pub dmacr: Field,
|
||||
/// Test Control register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -479,7 +770,7 @@ pub mod uart {
|
|||
/// - 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;
|
||||
pub itcr: Field,
|
||||
/// Integration Test Input register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -488,7 +779,7 @@ pub mod uart {
|
|||
/// - 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;
|
||||
pub itip: Field,
|
||||
/// Integration Test Output register, 32 bits long.
|
||||
///
|
||||
/// # Bits distribution:
|
||||
|
@ -510,12 +801,82 @@ pub mod uart {
|
|||
/// - 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;
|
||||
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 const TDR: usize = UART_START + 0x8C;
|
||||
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,13 +27,13 @@ impl Uart {
|
|||
self.flush();
|
||||
|
||||
// Stop UART
|
||||
TMP_UARTEN.read_and_write(0);
|
||||
self.memory_map.cr_uarten.read_and_write(0);
|
||||
|
||||
// Flush the FIFOs
|
||||
TMP_FEN.read_and_write(0);
|
||||
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.
|
||||
|
@ -52,38 +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?
|
||||
TMP_IBRD.write_without_read(26);
|
||||
TMP_FBRD.write_without_read(3);
|
||||
self.memory_map.ibrd.write_without_read(26);
|
||||
self.memory_map.fbrd.write_without_read(3);
|
||||
|
||||
// Set word len to 8
|
||||
let lcrh_val = TMP_WLEN.read_and_write_to_u32(0b11, 0);
|
||||
let lcrh_val = self.memory_map.lcrh_wlen.read_and_write_to_u32(0b11, 0);
|
||||
// Reenable the FIFOs
|
||||
let lcrh_val = TMP_FEN.read_and_write_to_u32(1, lcrh_val);
|
||||
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 cr_val = TMP_TXE.read_and_write_to_u32(1, 0);
|
||||
// TODO: let cr_val = TMP_RXE.read_and_write_to_u32(1, 0); to enable read
|
||||
unsafe { write_volatile(CR.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
|
||||
|
||||
self.memory_map.cr_uarten.read_and_write(1);
|
||||
self.initialized = true;
|
||||
TMP_UARTEN.read_and_write(1);
|
||||
}
|
||||
|
||||
/// Test if the UART is busy.
|
||||
fn is_busy(&self) -> bool {
|
||||
TMP_BUSY.read() != 0
|
||||
self.memory_map.fr_busy.read() != 0
|
||||
}
|
||||
|
||||
/// Test if the the TX FIFO is full.
|
||||
fn is_tx_full(&self) -> bool {
|
||||
TMP_TXFF.read() != 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' {
|
||||
|
@ -96,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");
|
||||
|
@ -106,12 +94,12 @@ impl Write for Uart {
|
|||
let _ = gpio::set_pin_output_state(20, gpio::PinOutputState::High);
|
||||
unsafe { asm!("nop") };
|
||||
}
|
||||
TMP_DATA.write_without_read(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)
|
||||
}
|
||||
|
||||
|
@ -122,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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue