Работа с TWI (I2C)

Для работы с большим количеством устройств придумали I2C. У nRF52 I2C называется TWI. Самое время его изучить.

У nRF52 TWI разделен на две части - это TWIM и TWIS:

  • TWIM - это TWI работающий в роли мастера, подходит для управления разными устройствами.
  • TWIS - это TWI подходящий для работы в роли например сенсора, оно общается с мастером, но не управляет обменом информацией.

В проект добавьте модули gpio , twim или twis в импорт crabik_board::hal. Часто используемый режим - TWI мастер, поэтому примеры далее будут про twim модуль. Напишите следующий код:


#![allow(unused)]
fn main() {
// Разделение GPIO на отдельные пины
let port0 = gpio::p0::Parts::new(periph.P0);
// Макрос который переименовывает пины микроконтроллера в названия пинов на плате
let pins = crabik_board::rename_pins!(port0);

// Подготовка пинов
let scl = pins.d9.into_floating_input().degrade();
let sda = pins.d10.into_floating_input().degrade();

// Подготовка к работе TWI мастера
let mut i2c = twim::Twim::new(
    periph.TWIM0, 
    twim::Pins { scl, sda }, 
    twim::Frequency::K100
);

// Создание буферов для передачи и приема данных
let mut tx_buffer = [0u8; 255];
let mut rx_buffer = [0u8; 255];

let data = [1, 2, 3, 4, 5, 6, 7, 8];
// Копируем все данные в буфер, что бы EasyDMA работал с оперативной памятью, а не с флешем
tx_buffer[0..data.len()].copy_from_slice(&data);

// Передача данных на устройство по адресу 0x90
i2c.write(0x90, &tx_buffer)
    .expect("Не удалось передать данные на устройство по адресу 0x90");

// Прием данных от устройства по адресу 0x90
i2c.read(0x90, &mut rx_buffer)
    .expect("Не удалось получить данные от устройства по адресу 0x90");
}

В показанном выше примере настраиваются пины и сам TWI. После настройки TWI мы отправляем и принимаем "сырые" байты по адресу 0x90.