@@ 2,9 2,14 @@
 #include <stm32h747xx.h>
 #include <core_cm7.h>
 #include <stdlib.h>
+#include "usb_device.h"
+#include "exti.h"
+#include "registers.h"
+#include "pin.h"
 
+#define LED1_GPIO GPIOI
 #define LED1_PIN 12
-#define LED2_PIN 13
+/* #define LED2_PIN 13 */
 
 void hard_fault_handler() {
   while(1) {}
@@ 50,53 55,86 @@ void exti15_10_handler(void)
 
 void main()
 {
-  uint32_t *i1 = malloc(sizeof(uint32_t));
-  uint32_t *i2 = malloc(sizeof(uint32_t));
-
-  free(i1);
-
-  uint32_t *i3 = malloc(sizeof(uint32_t));
-
-  led_gpio_en();
-  led_input();
-  led_toggle();
-
+  // The hsi is by default on 64 MHz.
+  // TODO: plls? configure dividers (note the need of refclk being between 1 and
+  // 16 MHz, the hsi can stay at 64 MHz, and prescaler DIVM can be given to account for that)
+  // enable the pll1, wait for it to be ready, and
+  // switch the sys clock to pll1.
+  // Is this necessary for something though?
+
+  // Clocks section
+  // Enable hsi48 for usb
+  RCC->CR |= RCC_CR_HSI48ON;
+  while ((RCC->CR & RCC_CR_HSI48RDY) == 0);
+
+  // Clock gating
   RCC->APB4ENR |= RCC_APB4ENR_SYSCFGEN;
   volatile uint32_t dummy;
   dummy = RCC->APB4ENR;
   dummy = RCC->APB4ENR;
 
-  RCC->AHB4ENR |= (1 << RCC_AHB4ENR_GPIOCEN_Pos);
+  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN | RCC_AHB4ENR_GPIOBEN | RCC_AHB4ENR_GPIOCEN | RCC_AHB4ENR_GPIOHEN | RCC_AHB4ENR_GPIOIEN | RCC_AHB4ENR_GPIOJEN;
   dummy = RCC->AHB4ENR;
   dummy = RCC->AHB4ENR;
 
-  // pc13 input
-  GPIOC->MODER &= ~((0x3) << (13*2));
+  // Pins init
+  pin_t* led1 = pin_init(LED1_GPIO, LED1_PIN);
+  pin_into_output_pushpull(led1);
+  pin_toggle(led1);
+  pin_toggle(led1);
 
-  SYSCFG->EXTICR[3] |= (SYSCFG_EXTICR4_EXTI13_PC);
-  EXTI->RTSR1 |= EXTI_RTSR1_TR13;
-  EXTI->FTSR1 &= ~(EXTI_FTSR1_TR13);
-  EXTI->IMR1 |= EXTI_IMR1_IM13;
+  // pc13 input - wakeup button
+  pin_t* wkup = pin_init(GPIOC, 13);
+  pin_into_input(wkup);
 
-  NVIC_SetPriority(EXTI15_10_IRQn, 2);
-  NVIC_EnableIRQ(EXTI15_10_IRQn);
-  /* NVIC->IPR[EXTI15_10_IRQn] |= 2 << (8U - __NVIC_PRIO_BITS); */
-  /* NVIC->ISER[(((uint32_t)EXTI15_10_IRQn) >> 5UL)] = (1 << (EXTI15_10_IRQn & 0x1FUL)); */
+  exti_t* exti = exti_init(EXTI, SYSCFG);
+  //                        exti13  pc
+  exti_external_interrupt(exti, 13, 2);
+  exti_rising_interrupt(exti, 13);
 
-  __enable_irq();
+  exti_nvic_setup(exti, 13);
+  /* NVIC_SetPriority(EXTI15_10_IRQn, 2); */
+  /* NVIC_EnableIRQ(EXTI15_10_IRQn); */
 
-  while(1) {
-    int toggle = (GPIOC->IDR >> 13) & 1;
+  __enable_irq();
 
-    if (toggle) {
-      led_toggle();
-      while(1) {}
-    }
-  }
-  /* void* usb_otg = usb_device_init(USB_OTG_ADDR); */
-  /* usb_device_setup(usb_otg); */
+  // TODO: ULPI inputs to alternate mode...
+
+  pin_t* ulpi_ck = pin_init(GPIOA, 5);
+  pin_t* ulpi_stp = pin_init(GPIOC, 0);
+  pin_t* ulpi_dir = pin_init(GPIOI, 11);
+  pin_t* ulpi_nxt = pin_init(GPIOH, 4);
+
+  pin_t* ulpi_d0 = pin_init(GPIOA, 3);
+  pin_t* ulpi_d1 = pin_init(GPIOB, 0);
+  pin_t* ulpi_d2 = pin_init(GPIOB, 1);
+  pin_t* ulpi_d3 = pin_init(GPIOB, 10);
+  pin_t* ulpi_d4 = pin_init(GPIOB, 11);
+  pin_t* ulpi_d5 = pin_init(GPIOB, 12);
+  pin_t* ulpi_d6 = pin_init(GPIOB, 13);
+  pin_t* ulpi_d7 = pin_init(GPIOB, 5);
+  pin_t* otg_hs_overcurrent = pin_init(GPIOJ, 1);
+
+  pin_into_alternate_highspeed(ulpi_ck, 10);
+  pin_into_alternate_highspeed(ulpi_stp, 10);
+  pin_into_alternate_highspeed(ulpi_dir, 10);
+  pin_into_alternate_highspeed(ulpi_nxt, 10);
+  pin_into_alternate_highspeed(ulpi_d0, 10);
+  pin_into_alternate_highspeed(ulpi_d1, 10);
+  pin_into_alternate_highspeed(ulpi_d2, 10);
+  pin_into_alternate_highspeed(ulpi_d3, 10);
+  pin_into_alternate_highspeed(ulpi_d4, 10);
+  pin_into_alternate_highspeed(ulpi_d5, 10);
+  pin_into_alternate_highspeed(ulpi_d6, 10);
+  pin_into_alternate_highspeed(ulpi_d7, 10);
+
+  // TODO: ?
+  pin_into_input_highspeed(otg_hs_overcurrent);
+
+  void* usb_otg = usb_device_init(USB1_OTG_HS, NULL, NULL);
+  usb_device_setup(usb_otg);
 
   /* usb_device_wait_for_handshake(usb_otg); */
 
-  /* // do two dummy reads after enabling the peripheral clock */
+  while(1) {}
 }