#include "at32f403a_407.h"
#include "usb.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_int.h"


usbd_core_type usb_core_dev;
extern usbd_class_handler usbd_rndis_cb;


//
void usb_init(void)
{
    gpio_init_type gpio_initstructure;
    
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    
    // Setup USB switch
    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
    
    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
    gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;  
    gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_initstructure.gpio_pins           = GPIO_PINS_9;
    gpio_init(GPIOE, &gpio_initstructure); 

    gpio_bits_reset(GPIOE, GPIO_PINS_9);
    
    usb_clock48m_select(USB_CLK_HICK);
        
    crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, TRUE);
    
    nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

    nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn, 6, 0);

    usbd_core_init(&usb_core_dev, USB, &usbd_rndis_cb, &USR_desc, 0);

    usbd_connect(&usb_core_dev);
}


//
void USBFS_L_CAN1_RX0_IRQHandler(void)
{
    usbd_irq_handler(&usb_core_dev);
}


//
void usb_stop(void)
{
    crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, FALSE);
    nvic_irq_disable(USBFS_L_CAN1_RX0_IRQn);
}
