diff --git a/firmware/App/Inc/tusb_config.h b/firmware/App/Inc/tusb_config.h index 1c0cbd3..c16c1d0 100644 --- a/firmware/App/Inc/tusb_config.h +++ b/firmware/App/Inc/tusb_config.h @@ -26,7 +26,7 @@ extern "C" { #define CFG_TUD_ENDPOINT0_SIZE 64 // Отладка -#define CFG_TUSB_DEBUG 2 +#define CFG_TUSB_DEBUG 0 #ifdef __cplusplus } diff --git a/firmware/App/Src/main.c b/firmware/App/Src/main.c index 2deb42b..56c94ba 100644 --- a/firmware/App/Src/main.c +++ b/firmware/App/Src/main.c @@ -3,46 +3,38 @@ #include "task.h" #include "tusb.h" -// Глобальная переменная для CMSIS -/* uint32_t SystemCoreClock = 72000000; */ - -// --- 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 + // ЯВНО обнуляем бит USBPRE (div 1.5 для получения 48MHz USB) + RCC->CFGR &= ~RCC_CFGR_USBPRE; // <-- ДОБАВЛЕНО! 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 --- - +// Задача USB (ТОЛЬКО tud_task, ничего больше!) void usb_device_task(void *param) { (void)param; - while (1) { tud_task(); } + while (1) { + tud_task(); + // Без задержки! tud_task() должен вызываться как можно чаще + } } +// Задача CDC void cdc_task(void *param) { (void)param; while (1) { - GPIOC->BSRR = GPIO_BSRR_BR13; // LED ON - vTaskDelay(pdMS_TO_TICKS(500)); - GPIOC->BSRR = GPIO_BSRR_BS13; // LED OFF - vTaskDelay(pdMS_TO_TICKS(500)); if (tud_cdc_connected()) { if (tud_cdc_available()) { uint8_t buf[64]; @@ -51,57 +43,67 @@ void cdc_task(void *param) { tud_cdc_write_flush(); } } - vTaskDelay(pdMS_TO_TICKS(1)); + vTaskDelay(pdMS_TO_TICKS(10)); // 10мс достаточно + } +} + +// Задача LED (отдельно!) +void led_task(void *param) { + (void)param; + while (1) { + GPIOC->BSRR = GPIO_BSRR_BR13; // LED ON + vTaskDelay(pdMS_TO_TICKS(500)); + GPIOC->BSRR = GPIO_BSRR_BS13; // LED OFF + vTaskDelay(pdMS_TO_TICKS(500)); } } -// Программный сброс USB (Soft-Connect) void force_usb_reset(void) { - // Включаем тактирование порта A RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; - - // Настраиваем PA12 (USB D+) как Output Push-Pull GPIOA->CRH &= ~GPIO_CRH_CNF12; - GPIOA->CRH |= GPIO_CRH_MODE12_1; // Output 2MHz - - // Прижимаем к земле (Logic 0) на 10 мс + GPIOA->CRH |= GPIO_CRH_MODE12_1; GPIOA->BSRR = GPIO_BSRR_BR12; - for (volatile int i = 0; i < 500000; i++) __NOP(); // ~10ms при 72MHz - - // Возвращаем в состояние Input Floating + for (volatile int i = 0; i < 500000; i++) __NOP(); GPIOA->CRH &= ~GPIO_CRH_MODE12; - GPIOA->CRH |= GPIO_CRH_CNF12_0; // Floating input + GPIOA->CRH |= GPIO_CRH_CNF12_0; } int main(void) { SystemClock_Config(); - // Моргаем светодиодом - RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Включаем GPIOC - GPIOC->CRH &= ~GPIO_CRH_CNF13; // PC13 (LED) - GPIOC->CRH |= GPIO_CRH_MODE13_1; // Output 2MHz + // Настройка LED + RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; + GPIOC->CRH &= ~GPIO_CRH_CNF13; + GPIOC->CRH |= GPIO_CRH_MODE13_1; force_usb_reset(); - // Включаем тактирование USB и GPIOA + // Включаем USB RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; RCC->APB1ENR |= RCC_APB1ENR_USBEN; - // ВКЛЮЧАЕМ ПРЕРЫВАНИЯ USB (КРИТИЧНО!) + // Прерывания USB NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn); NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_EnableIRQ(USBWakeUp_IRQn); tusb_init(); - xTaskCreate(usb_device_task, "usbd", 128, NULL, 3, NULL); - xTaskCreate(cdc_task, "cdc", 128, NULL, 2, NULL); + // УВЕЛИЧИЛИ стек до 256! + xTaskCreate( + usb_device_task, + "usbd", + 256, + NULL, + configMAX_PRIORITIES - 1, + NULL); + xTaskCreate(cdc_task, "cdc", 256, NULL, configMAX_PRIORITIES - 2, NULL); + xTaskCreate(led_task, "led", 128, NULL, 1, NULL); vTaskStartScheduler(); while (1); } -// Обработчики прерываний void USB_HP_CAN1_TX_IRQHandler(void) { tud_int_handler(0); }