#![no_main]
#![no_std]

extern crate panic_semihosting;

use rtic::app;

use cortex_m::asm::delay;
use stm32f1xx_hal::{
    gpio::{gpioc::*, Output, PushPull},
    i2c::{BlockingI2c, Mode},
    pac::{Peripherals},
    prelude::*,
    usb::{Peripheral, UsbBus, UsbBusType},
};
use embedded_hal::digital::v2::OutputPin;

use usb_device::bus;
use usb_device::prelude::*;

use usbd_webusb::WebUsb;

mod i2c;
mod print;

/// The main RTIC application object. See RTIC documentation for more information about how to read
/// this.
#[app(device = stm32f1xx_hal::stm32, peripherals = true)]
const APP: () = {
    struct Resources {
        usb_dev: UsbDevice<'static, UsbBusType>,
        webusb: WebUsb<UsbBusType>,
        // The I2C USB device class that performs the main logic of accessing the I2C bus over USB
        // for users of the device.
        i2c: i2c::I2CClass<'static, UsbBusType, PC13<Output<PushPull>>>,
    }

    /// Idle loop to prevent WFI which in turn prevents debugging.
    // TODO: make this only happen on debug builds?
    #[idle]
    fn idle(_: idle::Context) -> ! {
        loop {}
    }

    #[init]
    fn init(cx: init::Context) -> init::LateResources {
        static mut USB_BUS: Option<bus::UsbBusAllocator<UsbBusType>> = None;

        let mut flash = cx.device.FLASH.constrain();
        let mut rcc = cx.device.RCC.constrain();

        let clocks = rcc
            .cfgr
            .use_hse(8.mhz())
            .sysclk(48.mhz())
            .pclk1(24.mhz())
            .freeze(&mut flash.acr);

        assert!(clocks.usbclk_valid());

        let mut gpioa = cx.device.GPIOA.split(&mut rcc.apb2);
        let mut gpiob = cx.device.GPIOB.split(&mut rcc.apb2);
        let mut gpioc = cx.device.GPIOC.split(&mut rcc.apb2);

        // Active-low LED on bluepill board.
        let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
        led.set_high().ok();

        let mut afio = cx.device.AFIO.constrain(&mut rcc.apb2);

        // BluePill board has a pull-up resistor on the D+ line.
        // Pull the D+ pin down to send a RESET condition to the USB bus.
        // This forced reset is needed only for development, without it host
        // will not reset your device when you upload new firmware.
        let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh);
        usb_dp.set_low().unwrap();
        delay(clocks.sysclk().0 / 100);

        let usb_dm = gpioa.pa11;
        let usb_dp = usb_dp.into_floating_input(&mut gpioa.crh);

        let usb = Peripheral {
            usb: cx.device.USB,
            pin_dm: usb_dm,
            pin_dp: usb_dp,
        };

        *USB_BUS = Some(UsbBus::new(usb));

        let i2c_pins = (
            gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl),
            gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl),
        );

        // Blocking I2C peripheral for use by the I2C app.
        let i2c_dev = BlockingI2c::i2c1(
            cx.device.I2C1,
            i2c_pins,
            &mut afio.mapr,
            Mode::standard(100.khz()),
            clocks,
            &mut rcc.apb1,
            1000, 10, 1000, 1000,
        );

        // I2C app.
        let i2c = i2c::I2CClass::new(
            USB_BUS.as_ref().unwrap(),
            led, i2c_dev,
         );

        let usb_dev = UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x16c0, 0x27d8))
            .manufacturer("Warsaw Hackerspace")
            .product("Web I2C Programmer")
            // TODO(q3k): generate serial at build time?
            .serial_number("2137")
            .build();

        init::LateResources {
            usb_dev, i2c,
            webusb: WebUsb::new(
                USB_BUS.as_ref().unwrap(),
                usbd_webusb::url_scheme::HTTPS,
                "hackdoc.hackerspace.pl/dc/hbj11/flasher",
            ),
        }
    }

    #[task(binds = USB_LP_CAN_RX0, resources = [usb_dev, webusb, i2c])]
    fn usb_lp(cx: usb_lp::Context) {
        cx.resources
            .usb_dev
            .poll(&mut [cx.resources.webusb, cx.resources.i2c]);
    }
};

