#![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]);
    }
};

