#include <stdint.h>
#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 */
void hard_fault_handler() {
while(1) {}
}
void usage_fault_handler() {
while(1) {}
}
void nmi_handler() {
while(1) {}
}
void bus_fault_handler() {
while(1) {}
}
void led_toggle()
{
GPIOI->ODR ^= (1 << LED1_PIN);
}
void led_input()
{
GPIOI->MODER = (1 << LED1_PIN*2);
}
void led_gpio_en()
{
RCC->AHB4ENR |= (1 << RCC_AHB4ENR_GPIOIEN_Pos);
volatile uint32_t dummy;
dummy = RCC->AHB4ENR;
dummy = RCC->AHB4ENR;
}
void exti15_10_handler(void)
{
if (EXTI->PR1 & EXTI_PR1_PR13) {
led_toggle();
EXTI->PR1 &= EXTI_PR1_PR13;
}
}
void main()
{
// 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 |= RCC_AHB4ENR_GPIOAEN | RCC_AHB4ENR_GPIOBEN | RCC_AHB4ENR_GPIOCEN | RCC_AHB4ENR_GPIOHEN | RCC_AHB4ENR_GPIOIEN | RCC_AHB4ENR_GPIOJEN;
dummy = RCC->AHB4ENR;
dummy = RCC->AHB4ENR;
// Pins init
pin_t* led1 = pin_init(LED1_GPIO, LED1_PIN);
pin_into_output_pushpull(led1);
pin_toggle(led1);
pin_toggle(led1);
// pc13 input - wakeup button
pin_t* wkup = pin_init(GPIOC, 13);
pin_into_input(wkup);
exti_t* exti = exti_init(EXTI, SYSCFG);
// exti13 pc
exti_external_interrupt(exti, 13, 2);
exti_rising_interrupt(exti, 13);
exti_nvic_setup(exti, 13);
/* NVIC_SetPriority(EXTI15_10_IRQn, 2); */
/* NVIC_EnableIRQ(EXTI15_10_IRQn); */
__enable_irq();
// 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);
while(1) {}
}