解答例

#![deny(unsafe_code)]
#![no_main]
#![no_std]

use cortex_m_rt::entry;
use rtt_target::{rtt_init_print, rprintln};
use panic_rtt_target as _;

#[cfg(feature = "v1")]
use microbit::{
    hal::twi,
    pac::twi0::frequency::FREQUENCY_A,
};

#[cfg(feature = "v2")]
use microbit::{
    hal::twim,
    pac::twim0::frequency::FREQUENCY_A,
};

use lsm303agr::{
    AccelScale, AccelOutputDataRate, Lsm303agr,
};

use microbit::hal::timer::Timer;
use microbit::hal::prelude::*;
use nb::Error;

#[entry]
fn main() -> ! {
    const THRESHOLD: f32 = 0.5;

    rtt_init_print!();
    let board = microbit::Board::take().unwrap();

    #[cfg(feature = "v1")]
    let i2c = { twi::Twi::new(board.TWI0, board.i2c.into(), FREQUENCY_A::K100) };

    #[cfg(feature = "v2")]
    let i2c = { twim::Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::K100) };

    let mut countdown = Timer::new(board.TIMER0);
    let mut delay = Timer::new(board.TIMER1);
    let mut sensor = Lsm303agr::new_with_i2c(i2c);
    sensor.init().unwrap();
    sensor.set_accel_odr(AccelOutputDataRate::Hz50).unwrap();
    // 16Gまで計測できるようにセンサの設定を変更。
    // 人のパンチは案外速いものです。
    sensor.set_accel_scale(AccelScale::G16).unwrap();

    let mut max_g = 0.;
    let mut measuring = false;

    loop {
        while !sensor.accel_status().unwrap().xyz_new_data {}
        // X軸の加速度をg単位で取得
        let g_x = sensor.accel_data().unwrap().x as f32 / 1000.0;

        if measuring {
            // contdownタイマのステータスをチェック
            match countdown.wait() {
                // countdownはまだ終わっていない
                Err(Error::WouldBlock) => {
                    if g_x > max_g {
                        max_g = g_x;
                    }
                },
                // countdown終了
                Ok(_) => {
                    // 最大加速度を報告
                    rprintln!("Max acceleration: {}g", max_g);

                    // リセット
                    max_g = 0.;
                    measuring = false;
                },
                // nrf52とnrf51のHALはエラー型としてVoidを返します。
                // VoidはEmpty型なので、ここにたどり着くことはありません。
                Err(Error::Other(_)) => {
                    unreachable!()
                }
            }
        } else {
            // 加速度がしきい値を超えれば測定を開始
            if g_x > THRESHOLD {
                rprintln!("START!");

                measuring = true;
                max_g = g_x;
                // ドキュメンテーションによると、タイマは1Mhzで動作します。
                // よって、1秒待つためには1_000_000ティック必要です。
                countdown.start(1_000_000_u32);
            }
        }
        delay.delay_ms(20_u8);
    }
}