#![no_std]
#![no_main]

use embedded_hal::digital::OutputPin;
use embedded_hal::spi::{self, SpiBus};
use cortex_m_rt::entry;
use rtt_target::{rprintln, rtt_init_print};
use nrf52840_hal as hal;
use nrf52840_hal::{
    gpio::*,
    pac,
    spim::Spim,
};

fn spi_loopback<E: spi::Error>(spi: &mut impl
        SpiBus<Error = E>) -> Result<(), E> {
    let reference_data = b"Hello,echo Loopback!";
    // DMA を使用するので送信データを RAM に配置する
    let test_vec1: [u8; 20] = *reference_data;
    let mut readbuf = [0u8; 20];
    spi.transfer(&mut readbuf, &test_vec1)?;
    rprintln!("Read buffer: {}", core::str::
                  from_utf8(&readbuf).unwrap());
    Ok(())
}

/// SPI loopback example.
/// Connect P0.27 (MISO) to P0.26 (MOSI).
#[entry]
fn main() -> ! {
    rtt_init_print!();
    let p = pac::Peripherals::take().unwrap();
    let port0 = p0::Parts::new(p.P0);

    let mut cs = port0.p0_21.into_push_pull_output(
        Level::Low).degrade();
    let spiclk = port0.p0_25.into_push_pull_output(
        Level::Low).degrade();
    let spimosi = port0.p0_26.into_push_pull_output(
        Level::Low).degrade();
    let spimiso = port0.p0_27.into_floating_input().
                      degrade();

    let pins = hal::spim::Pins {
        sck: Some(spiclk),
        miso: Some(spimiso),
        mosi: Some(spimosi),
    };

    let mut spi = Spim::new(p.SPIM2, pins, hal::
      spim::Frequency::K125, hal::spim::MODE_0, 0);
    rprintln!("SPI loopback example starting");

    cs.set_high().expect("Failed to set CS high");
    spi_loopback(&mut spi).expect(
                        "Error in spi_loopback");
    cs.set_low().expect("Failed to set CS low");

    loop {}
}
