#include <stdint.h>
#include <stm32h747xx.h>
#include <core_cm7.h>
#include <stdlib.h>
#include "delay.h"
#include "usb_device.h"
#include "usb_device_cdc.h"
#include "clocks.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()
{
systick_configure();
// Clocks section
// Enable hsi48 for usb
RCC->CR |= RCC_CR_HSI48ON;
while ((RCC->CR & RCC_CR_HSI48RDY) == 0);
// TODO: pll, system clock switch... too complicated it seems.
// Getting hard faults, apparently because of too low voltage
// Has to be enabled before vco can be changed
/* PWR->CR3 |= PWR_CR3_LDOEN; */
/* PWR->CR3 &= ~PWR_CR3_LDOEN; */
/* reg_write_bits_pos(&PWR->D3CR, 2, PWR_D3CR_VOS_Pos, 3); */
/* /\* SYSCFG->PWRCR |= SYSCFG_PWRCR_ODEN; *\/ */
/* while((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0); */
/* /\* while((PWR->D3CR & PWR_D3CR_VOSRDY) == 0); *\/ */
/* reg_write_bits(&FLASH->ACR, FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_Msk); */
/* // HSI is 64 MHz, not divided */
/* // Diving by 32 to put to PLL -> 2 MHz */
/* // DIVN = 360 -> F_VCO = 720 MHz */
/* // DIVP = 2 -> pll1_p is 360 MHz */
/* // DIVQ = 8 -> pll1_q is 90 MHz */
/* // DIVR = 8 -> pll1_r is 90 MHz */
/* clocks_pll_configure(CLOCK_PLL1, 32, PLL_SOURCE_HSI, */
/* 360, 2, 8, 8); */
/* clocks_pll_enable(CLOCK_PLL1); */
/* clocks_pll_wait_ready(CLOCK_PLL1, 300); */
/* clocks_system_clock_source(CLOCK_SOURCE_PLL_1_P_CK, */
/* 1, 1, 2, 300); */
// 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, LED1_GPIO, LED1_PIN);
pin_into_output_pushpull(&led1);
pin_toggle(&led1);
pin_toggle(&led1);
// pc13 input - wakeup button
pin_t wkup;
pin_init(&wkup, GPIOC, 13);
pin_into_input(&wkup);
exti_t exti_wkup;
exti_init(&exti_wkup, 13, EXTI, SYSCFG);
exti_external_interrupt(&exti_wkup, EXTI_GPIOC);
exti_rising_interrupt(&exti_wkup);
exti_enable_interrupt(&exti_wkup);
/* NVIC_SetPriority(EXTI15_10_IRQn, 2); */
/* NVIC_EnableIRQ(EXTI15_10_IRQn); */
__enable_irq();
pin_t ulpi_clk, ulpi_stp, ulpi_dir, ulpi_nxt,
ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4,
ulpi_d5, ulpi_d6, ulpi_d7, otg_hs_overcurrent;
pin_init(&ulpi_clk, GPIOA, 5);
pin_init(&ulpi_stp, GPIOC, 0);
pin_init(&ulpi_dir, GPIOI, 11);
pin_init(&ulpi_nxt, GPIOH, 4);
pin_init(&ulpi_d0, GPIOA, 3);
pin_init(&ulpi_d1, GPIOB, 0);
pin_init(&ulpi_d2, GPIOB, 1);
pin_init(&ulpi_d3, GPIOB, 10);
pin_init(&ulpi_d4, GPIOB, 11);
pin_init(&ulpi_d5, GPIOB, 12);
pin_init(&ulpi_d6, GPIOB, 13);
pin_init(&ulpi_d7, GPIOB, 5);
pin_init(&otg_hs_overcurrent, GPIOJ, 1);
pin_into_alternate_highspeed(&ulpi_clk, 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);
// TODO: why can't I send string descriptors?
void *usb_dev = usb_device_init(USB_OTG_HS1, &USB_CLASS_CDC_ACM,
0x1234, 0x1111, u"Frantisek Bohacek",
u"Display", 1, NULL);
cdc_acm_configure(usb_dev, 512);
usb_device_setup(usb_dev);
usb_device_wait_for_handshake(usb_dev);
uint8_t data[64];
while (1) {
uint16_t received = cdc_data_receive(usb_dev, data, 64);
for (uint16_t i = 0; i < received; i++) {
data[i] = data[i] + 1;
}
if (received > 0) {
cdc_data_send_blocking(usb_dev, data, received);
}
if (pin_read(&wkup)) {
cdc_data_send_blocking(usb_dev, (uint8_t*)"Hello world!\r\n", 0);
}
}
}