Сирий ввід вивід з відображеної пам'яті (MMIO)

Більшість мікроконтролерів отримують доступ до периферійних пристроїв через відображений в пам’ять IO. Давайте спробуємо включити світлодіод на нашому micro:bit:

#![no_main]
#![no_std]

extern crate panic_halt as _;

mod interrupts;

use core::mem::size_of;
use cortex_m_rt::entry;

/// Периферійна адреса порту GPIO 0
const GPIO_P0: usize = 0x5000_0000;

// Зміщення периферії GPIO
const PIN_CNF: usize = 0x700;
const OUTSET: usize = 0x508;
const OUTCLR: usize = 0x50c;

// Поля PIN_CNF
const DIR_OUTPUT: u32 = 0x1;
const INPUT_DISCONNECT: u32 = 0x1 << 1;
const PULL_DISABLED: u32 = 0x0 << 2;
const DRIVE_S0S1: u32 = 0x0 << 8;
const SENSE_DISABLED: u32 = 0x0 << 16;

#[entry]
fn main() -> ! {
    // Налаштуйте виводи GPIO 0 21 та 28 як push-pull виводи.
    let pin_cnf_21 = (GPIO_P0 + PIN_CNF + 21 * size_of::<u32>()) as *mut u32;
    let pin_cnf_28 = (GPIO_P0 + PIN_CNF + 28 * size_of::<u32>()) as *mut u32;
    // БЕЗПЕКА: вказівники вказують на дійсні периферійні регістри 
    // керування, і ніяких псевдонімів не існує.
    unsafe {
        pin_cnf_21.write_volatile(
            DIR_OUTPUT
                | INPUT_DISCONNECT
                | PULL_DISABLED
                | DRIVE_S0S1
                | SENSE_DISABLED,
        );
        pin_cnf_28.write_volatile(
            DIR_OUTPUT
                | INPUT_DISCONNECT
                | PULL_DISABLED
                | DRIVE_S0S1
                | SENSE_DISABLED,
        );
    }

    // Встановіть низький рівень на виводі 28 і високий на виводі 21, щоб увімкнути світлодіод.
    let gpio0_outset = (GPIO_P0 + OUTSET) as *mut u32;
    let gpio0_outclr = (GPIO_P0 + OUTCLR) as *mut u32;
    // БЕЗПЕКА: вказівники вказують на дійсні периферійні регістри 
    // керування, і ніяких псевдонімів не існує.
    unsafe {
        gpio0_outclr.write_volatile(1 << 28);
        gpio0_outset.write_volatile(1 << 21);
    }

    loop {}
}
  • Вивід 21 GPIO 0 підключений до першого стовпчика світлодіодної матриці, а вивід 28 – до першого рядка.

Запустіть приклад за допомогою:

cargo embed --bin mmio