๋“œ๋ผ์ด๋ฒ„

์ด์ œ ๋“œ๋ผ์ด๋ฒ„์—์„œ ์ƒˆ๋กœ์šด Registers ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

/// PL011 UART์šฉ ๋“œ๋ผ์ด๋ฒ„
#[derive(Debug)]
pub struct Uart {
    registers: *mut Registers,
}

impl Uart {
    /// ์ง€์ •๋œ ๊ธฐ๋ณธ ์ฃผ์†Œ์— PL011 ๊ธฐ๊ธฐ์— ๋Œ€ํ•œ UART ๋“œ๋ผ์ด๋ฒ„์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ
 /// ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
 ///
 /// # ์•ˆ์ „
 ///
 /// ์ง€์ •๋œ ๊ธฐ๋ณธ ์ฃผ์†Œ๋Š” PL011 ๊ธฐ๊ธฐ์˜
 /// MMIO ์ œ์–ด ๋ ˆ์ง€์Šคํ„ฐ 8๊ฐœ๋ฅผ ๊ฐ€๋ฆฌ์ผœ์•ผ ํ•˜๋ฉฐ,
 /// ์ด๋Š” ํ”„๋กœ์„ธ์Šค์˜ ์ฃผ์†Œ ๊ณต๊ฐ„์— ๊ธฐ๊ธฐ ๋ฉ”๋ชจ๋ฆฌ๋กœ
 /// ๋งคํ•‘๋˜์–ด์•ผ ํ•˜๋ฉฐ ๋‹ค๋ฅธ ๋ณ„์นญ์€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    pub unsafe fn new(base_address: *mut u32) -> Self {
        Self { registers: base_address as *mut Registers }
    }

    /// UART์— ๋‹จ์ผ ๋ฐ”์ดํŠธ๋ฅผ ์”๋‹ˆ๋‹ค.
    pub fn write_byte(&self, byte: u8) {
        // TX ๋ฒ„ํผ์— ๊ณต๊ฐ„์ด ํ™•๋ณด๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
        while self.read_flag_register().contains(Flags::TXFF) {}

        // self.registers๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ๋งคํ•‘๋œ PL011 ๊ธฐ๊ธฐ์˜ ์ œ์–ด ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ
        // ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.
        unsafe {
            // TX ๋ฒ„ํผ์— ์”๋‹ˆ๋‹ค.
            addr_of_mut!((*self.registers).dr).write_volatile(byte.into());
        }

        // UART๊ฐ€ ๋” ์ด์ƒ ์‚ฌ์šฉ ์ค‘์ด ์•„๋‹ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
        while self.read_flag_register().contains(Flags::BUSY) {}
    }

    /// Reads and returns a pending byte, or `None` if nothing has been
    /// received.
    pub fn read_byte(&self) -> Option<u8> {
        if self.read_flag_register().contains(Flags::RXFE) {
            None
        } else {
            let data = unsafe { addr_of!((*self.registers).dr).read_volatile() };
            // TODO: ๋น„ํŠธ 8~11์—์„œ ์˜ค๋ฅ˜ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
            Some(data as u8)
        }
    }

    fn read_flag_register(&self) -> Flags {
        // self.registers๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ๋งคํ•‘๋œ PL011 ๊ธฐ๊ธฐ์˜ ์ œ์–ด ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ
        // ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.
        unsafe { addr_of!((*self.registers).fr).read_volatile() }
    }
}
  • addr_of! / addr_of_mut!๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘๊ฐ„ ์ฐธ์กฐ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ฐœ๋ณ„ ํ•„๋“œ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์€ ๋ถˆ์•ˆ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.