kopia lustrzana https://github.com/skuep/AIOC
165 wiersze
3.9 KiB
C
165 wiersze
3.9 KiB
C
#include "usb.h"
|
|
#include "stm32f3xx_hal.h"
|
|
#include "aioc.h"
|
|
#include "tusb.h"
|
|
#include "usb_serial.h"
|
|
#include "usb_audio.h"
|
|
#include "usb_hid.h"
|
|
|
|
// We have ISOCHRONOUS endpoints defined that share the same endpoint number, but have opposing directions.
|
|
// However with STM32 hardware, ISOCHRONOUS endpoints use both RX and TX structures of the same endpoint register in hardware
|
|
// We circumvent a clash by defining our own custom endpoint map for the tiny usb stack.
|
|
// This callback is probably not needed with new versions of tinyusb
|
|
uint8_t tu_stm32_edpt_number_cb(uint8_t addr)
|
|
{
|
|
switch (addr) {
|
|
case 0x00:
|
|
case 0x80:
|
|
/* Endpoint Zero */
|
|
return 0x00;
|
|
|
|
case EPNUM_AUDIO_IN:
|
|
return 0x01;
|
|
|
|
case EPNUM_AUDIO_OUT:
|
|
return 0x02;
|
|
|
|
case EPNUM_AUDIO_FB:
|
|
return 0x03;
|
|
|
|
case EPNUM_HID_IN:
|
|
case EPNUM_HID_OUT:
|
|
return 0x04;
|
|
|
|
case EPNUM_CDC_0_OUT:
|
|
case EPNUM_CDC_0_IN:
|
|
return 0x05;
|
|
|
|
case EPNUM_CDC_0_NOTIF:
|
|
return 0x06;
|
|
|
|
default:
|
|
TU_BREAKPOINT();
|
|
return 0x00;
|
|
}
|
|
}
|
|
|
|
// FIXME: Do all three need to be handled, or just the LP one?
|
|
// USB high-priority interrupt (Channel 74): Triggered only by a correct
|
|
// transfer event for isochronous and double-buffer bulk transfer to reach
|
|
// the highest possible transfer rate.
|
|
void USB_HP_IRQHandler(void)
|
|
{
|
|
tud_int_handler(0);
|
|
}
|
|
|
|
// USB low-priority interrupt (Channel 75): Triggered by all USB events
|
|
// (Correct transfer, USB reset, etc.). The firmware has to check the
|
|
// interrupt source before serving the interrupt.
|
|
void USB_LP_IRQHandler(void)
|
|
{
|
|
tud_int_handler(0);
|
|
}
|
|
|
|
// USB wakeup interrupt (Channel 76): Triggered by the wakeup event from the USB
|
|
// Suspend mode.
|
|
void USBWakeUp_RMP_IRQHandler(void)
|
|
{
|
|
tud_int_handler(0);
|
|
}
|
|
|
|
// Invoked when device is mounted (configured)
|
|
void tud_mount_cb(void)
|
|
{
|
|
|
|
}
|
|
|
|
// Invoked when device is unmounted
|
|
void tud_umount_cb(void)
|
|
{
|
|
|
|
}
|
|
|
|
// Invoked when usb bus is suspended
|
|
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
|
|
void tud_suspend_cb(bool remote_wakeup_en)
|
|
{
|
|
|
|
}
|
|
|
|
// Invoked when usb bus is resumed
|
|
void tud_resume_cb(void)
|
|
{
|
|
|
|
}
|
|
|
|
void Timer_Init(void)
|
|
{
|
|
__HAL_RCC_TIM2_CLK_ENABLE();
|
|
|
|
/* TIM2 generates a timebase for USB OUT feedback endpoint */
|
|
USB_SOF_TIMER->CR1 = TIM_CLOCKDIVISION_DIV1 | TIM_COUNTERMODE_UP | TIM_AUTORELOAD_PRELOAD_ENABLE;
|
|
USB_SOF_TIMER->PSC = 0;
|
|
USB_SOF_TIMER->ARR = 0xFFFFFFFFUL;
|
|
USB_SOF_TIMER->CCMR1 = (0x1 << TIM_CCMR1_CC1S_Pos);
|
|
USB_SOF_TIMER->EGR = TIM_EGR_UG;
|
|
USB_SOF_TIMER->CR1 |= TIM_CR1_CEN;
|
|
|
|
TU_ASSERT((2 * HAL_RCC_GetPCLK1Freq()) == USB_SOF_TIMER_HZ, /**/);
|
|
}
|
|
|
|
void GPIO_Init(void)
|
|
{
|
|
/* Configure USB DM and DP pins */
|
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
|
GPIO_InitTypeDef GPIO_InitStruct;
|
|
GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
GPIO_InitStruct.Alternate = GPIO_AF14_USB;
|
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
|
}
|
|
|
|
void USB_Reset(void)
|
|
{
|
|
/* pull USB DP pins low to simulate disconnect
|
|
to force the host to re-enumerate when a new program is loaded */
|
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
|
GPIO_InitTypeDef GPIO_InitStruct;
|
|
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
|
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
|
|
|
GPIOA->BRR = GPIO_PIN_12;
|
|
}
|
|
|
|
void USB_Init(void)
|
|
{
|
|
__HAL_REMAPINTERRUPT_USB_ENABLE();
|
|
__HAL_RCC_USB_CLK_ENABLE();
|
|
|
|
GPIO_Init();
|
|
Timer_Init();
|
|
|
|
// Init classes
|
|
USB_SerialInit();
|
|
USB_AudioInit();
|
|
USB_HIDInit();
|
|
|
|
// Start USB Stack
|
|
tud_init(BOARD_TUD_RHPORT);
|
|
|
|
NVIC_SetPriority(USB_LP_IRQn, AIOC_IRQ_PRIO_USB);
|
|
NVIC_SetPriority(USB_HP_IRQn, AIOC_IRQ_PRIO_USB);
|
|
}
|
|
|
|
void USB_Task(void)
|
|
{
|
|
USB_SerialTask();
|
|
tud_task();
|
|
}
|
|
|