#include "FreeRTOS.h" #include "stm32f1xx.h" #include "task.h" #include "tusb.h" // --- System Clock Config (72MHz from 8MHz HSE) --- void SystemClock_Config(void) { // Включаем HSE RCC->CR |= RCC_CR_HSEON; while (!(RCC->CR & RCC_CR_HSERDY)); // Настраиваем Flash latency (2 wait states) FLASH->ACR |= FLASH_ACR_LATENCY_2; // PLL: HSE * 9 = 72 MHz // PLLSRC = HSE (1), PLLMUL = 9 (0111) -> 0x001C0000 // USB Prescaler = 1.5 (Div by 1.5 -> 48MHz) -> 0x00000000 (PLL/1.5 is // default? No check bit) В F103 USBPRE бит в RCC_CFGR: 0 = div1.5, 1 = div1 // Мы хотим 72MHz sysclk. Для USB нужно 48MHz. // 72 / 1.5 = 48MHz. Значит USBPRE = 0 (reset state). RCC->CFGR |= (RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL9); // Включаем PLL RCC->CR |= RCC_CR_PLLON; while (!(RCC->CR & RCC_CR_PLLRDY)); // Переключаем System Clock на PLL RCC->CFGR |= RCC_CFGR_SW_PLL; while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); SystemCoreClock = 72000000; } // --- Задачи FreeRTOS --- // Задача для стека TinyUSB (обработка событий USB) void usb_device_task(void *param) { (void)param; while (1) { tud_task(); // "Сердце" TinyUSB. Должно вызываться часто. } } // Задача CDC (эхо) void cdc_task(void *param) { (void)param; while (1) { if (tud_cdc_connected()) { if (tud_cdc_available()) { uint8_t buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); tud_cdc_write(buf, count); // Эхо tud_cdc_write_flush(); } } vTaskDelay(pdMS_TO_TICKS(1)); } } int main(void) { SystemClock_Config(); // Включаем тактирование USB и GPIOA (для USB пинов) RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; RCC->APB1ENR |= RCC_APB1ENR_USBEN; // Инициализация TinyUSB tusb_init(); // Создание задач xTaskCreate( usb_device_task, "usbd", 128, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(cdc_task, "cdc", 128, NULL, configMAX_PRIORITIES - 2, NULL); vTaskStartScheduler(); while (1); } // --- Обработчики прерываний --- // USB High Priority or CAN1 TX (Не используется в FS, но полезно объявить) void USB_HP_CAN1_TX_IRQHandler(void) { tud_int_handler(0); } // USB Low Priority or CAN1 RX0 (Основное прерывание для F103) void USB_LP_CAN1_RX0_IRQHandler(void) { tud_int_handler(0); } // USB Wakeup void USBWakeUp_IRQHandler(void) { tud_int_handler(0); }