feat(firmware): добавлено моргание светодиодом
This commit is contained in:
@@ -3,6 +3,9 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
|
// Глобальная переменная для CMSIS
|
||||||
|
/* uint32_t SystemCoreClock = 72000000; */
|
||||||
|
|
||||||
// --- System Clock Config (72MHz from 8MHz HSE) ---
|
// --- System Clock Config (72MHz from 8MHz HSE) ---
|
||||||
void SystemClock_Config(void) {
|
void SystemClock_Config(void) {
|
||||||
// Включаем HSE
|
// Включаем HSE
|
||||||
@@ -13,11 +16,6 @@ void SystemClock_Config(void) {
|
|||||||
FLASH->ACR |= FLASH_ACR_LATENCY_2;
|
FLASH->ACR |= FLASH_ACR_LATENCY_2;
|
||||||
|
|
||||||
// PLL: HSE * 9 = 72 MHz
|
// 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);
|
RCC->CFGR |= (RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL9);
|
||||||
|
|
||||||
// Включаем PLL
|
// Включаем PLL
|
||||||
@@ -33,23 +31,23 @@ void SystemClock_Config(void) {
|
|||||||
|
|
||||||
// --- Задачи FreeRTOS ---
|
// --- Задачи FreeRTOS ---
|
||||||
|
|
||||||
// Задача для стека TinyUSB (обработка событий USB)
|
|
||||||
void usb_device_task(void *param) {
|
void usb_device_task(void *param) {
|
||||||
(void)param;
|
(void)param;
|
||||||
while (1) {
|
while (1) { tud_task(); }
|
||||||
tud_task(); // "Сердце" TinyUSB. Должно вызываться часто.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Задача CDC (эхо)
|
|
||||||
void cdc_task(void *param) {
|
void cdc_task(void *param) {
|
||||||
(void)param;
|
(void)param;
|
||||||
while (1) {
|
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_connected()) {
|
||||||
if (tud_cdc_available()) {
|
if (tud_cdc_available()) {
|
||||||
uint8_t buf[64];
|
uint8_t buf[64];
|
||||||
uint32_t count = tud_cdc_read(buf, sizeof(buf));
|
uint32_t count = tud_cdc_read(buf, sizeof(buf));
|
||||||
tud_cdc_write(buf, count); // Эхо
|
tud_cdc_write(buf, count);
|
||||||
tud_cdc_write_flush();
|
tud_cdc_write_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,42 +55,61 @@ void cdc_task(void *param) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Программный сброс 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->BSRR = GPIO_BSRR_BR12;
|
||||||
|
for (volatile int i = 0; i < 500000; i++) __NOP(); // ~10ms при 72MHz
|
||||||
|
|
||||||
|
// Возвращаем в состояние Input Floating
|
||||||
|
GPIOA->CRH &= ~GPIO_CRH_MODE12;
|
||||||
|
GPIOA->CRH |= GPIO_CRH_CNF12_0; // Floating input
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
SystemClock_Config();
|
SystemClock_Config();
|
||||||
|
|
||||||
// Включаем тактирование USB и GPIOA (для USB пинов)
|
// Моргаем светодиодом
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Включаем GPIOC
|
||||||
|
GPIOC->CRH &= ~GPIO_CRH_CNF13; // PC13 (LED)
|
||||||
|
GPIOC->CRH |= GPIO_CRH_MODE13_1; // Output 2MHz
|
||||||
|
|
||||||
|
force_usb_reset();
|
||||||
|
|
||||||
|
// Включаем тактирование USB и GPIOA
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
||||||
|
|
||||||
// Инициализация TinyUSB
|
// ВКЛЮЧАЕМ ПРЕРЫВАНИЯ USB (КРИТИЧНО!)
|
||||||
|
NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
|
||||||
|
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||||
|
NVIC_EnableIRQ(USBWakeUp_IRQn);
|
||||||
|
|
||||||
tusb_init();
|
tusb_init();
|
||||||
|
|
||||||
// Создание задач
|
xTaskCreate(usb_device_task, "usbd", 128, NULL, 3, NULL);
|
||||||
xTaskCreate(
|
xTaskCreate(cdc_task, "cdc", 128, NULL, 2, NULL);
|
||||||
usb_device_task,
|
|
||||||
"usbd",
|
|
||||||
128,
|
|
||||||
NULL,
|
|
||||||
configMAX_PRIORITIES - 1,
|
|
||||||
NULL);
|
|
||||||
xTaskCreate(cdc_task, "cdc", 128, NULL, configMAX_PRIORITIES - 2, NULL);
|
|
||||||
|
|
||||||
vTaskStartScheduler();
|
vTaskStartScheduler();
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Обработчики прерываний ---
|
// Обработчики прерываний
|
||||||
// USB High Priority or CAN1 TX (Не используется в FS, но полезно объявить)
|
|
||||||
void USB_HP_CAN1_TX_IRQHandler(void) {
|
void USB_HP_CAN1_TX_IRQHandler(void) {
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// USB Low Priority or CAN1 RX0 (Основное прерывание для F103)
|
|
||||||
void USB_LP_CAN1_RX0_IRQHandler(void) {
|
void USB_LP_CAN1_RX0_IRQHandler(void) {
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// USB Wakeup
|
|
||||||
void USBWakeUp_IRQHandler(void) {
|
void USBWakeUp_IRQHandler(void) {
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) -O2 -Wall -fdata-sections -ffunction-sec
|
|||||||
# Linker
|
# Linker
|
||||||
LDSCRIPT = stm32f103c8.ld
|
LDSCRIPT = stm32f103c8.ld
|
||||||
LIBS = -lc -lm -lnosys
|
LIBS = -lc -lm -lnosys
|
||||||
LDFLAGS = $(MCU) -T$(LDSCRIPT) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
|
LDFLAGS = $(MCU) -T$(LDSCRIPT) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections -Wl,--no-warn-rwx-segments
|
||||||
|
|
||||||
# --- Генерация списка объектов ---
|
# --- Генерация списка объектов ---
|
||||||
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
|
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ MEMORY
|
|||||||
/* Sections */
|
/* Sections */
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
/* Disable warning about RWX segment */
|
||||||
|
/* __GNU_EH_FRAME_HDR = 0; */
|
||||||
/* The startup code into "FLASH" Rom type memory */
|
/* The startup code into "FLASH" Rom type memory */
|
||||||
.isr_vector :
|
.isr_vector :
|
||||||
{
|
{
|
||||||
|
|||||||
1
firmware/system_stm32f1xx.c
Symbolic link
1
firmware/system_stm32f1xx.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/mikhail/repos/brightness-collector/firmware/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c
|
||||||
Reference in New Issue
Block a user