feat(mic): try1: setup sound with usb

This commit is contained in:
2025-12-25 21:06:50 +03:00
parent 2f0527a3d8
commit 3306b8083b
7 changed files with 411 additions and 22 deletions

View File

@@ -1,27 +1,30 @@
#include <stdio.h>
#include <string.h>
#include "FreeRTOS.h"
#include "audio_adc.h"
#include "stm32f1xx.h"
#include "task.h"
#include "tusb.h"
// System Clock Configuration
void SystemClock_Config(void) {
// Настройка на 72 MHz через HSE + PLL
// 1. Включаем HSE (внешний кварц 8 МГц)
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY));
// 2. Настраиваем Flash: 1 цикл ожидания (достаточно для 48 МГц)
FLASH->ACR = FLASH_ACR_LATENCY_1;
// 2. Настраиваем Flash: 2 цикла ожидания для 72 MHz
FLASH->ACR = FLASH_ACR_LATENCY_2;
// 3. Настраиваем PLL:
// Множитель x6: 8 МГц * 6 = 48 МГц
RCC->CFGR &= ~RCC_CFGR_PLLMULL; // Сброс битов множителя
RCC->CFGR |= RCC_CFGR_PLLMULL6;
// 3. Настраиваем PLL: 8 MHz * 9 = 72 MHz
RCC->CFGR &= ~RCC_CFGR_PLLMULL;
RCC->CFGR |= RCC_CFGR_PLLMULL9;
RCC->CFGR |= RCC_CFGR_PLLSRC; // Источник PLL = HSE
// Источник PLL = HSE
RCC->CFGR |= RCC_CFGR_PLLSRC;
// 4. Настраиваем USB делитель:
// USBPRE = 1 (делитель /1). Т.е. 48 МГц / 1 = 48 МГц
RCC->CFGR |= RCC_CFGR_USBPRE;
// 4. USB делитель: 72 MHz / 1.5 = 48 MHz
RCC->CFGR &= ~RCC_CFGR_USBPRE; // USBPRE = 0 (делитель 1.5)
// 5. Включаем PLL
RCC->CR |= RCC_CR_PLLON;
@@ -32,21 +35,79 @@ void SystemClock_Config(void) {
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
// Обновляем глобальную переменную частоты
SystemCoreClock = 48000000;
SystemCoreClock = 72000000;
}
// Задача USB
// Audio Processing Callback
// Буфер для отправки статистики через USB
static char usb_tx_buffer[128];
static volatile uint32_t total_samples = 0;
void audio_buffer_ready(audio_sample_t *buffer, uint32_t size) {
// Эта функция вызывается из прерывания DMA
// Не делать тяжелых операций здесь
total_samples += size;
// мин/макс значения
uint16_t min_val = 4095;
uint16_t max_val = 0;
uint32_t sum = 0;
for (uint32_t i = 0; i < size; i++) {
uint16_t val = buffer[i];
if (val < min_val) min_val = val;
if (val > max_val) max_val = val;
sum += val;
}
uint16_t avg = sum / size;
// Каждые 2 секунды отправляем статистику: каждый 100-й буфер
static uint32_t report_counter = 0;
report_counter++;
if (report_counter >= 100) {
report_counter = 0;
snprintf(
usb_tx_buffer,
sizeof(usb_tx_buffer),
"ADC Stats - Min: %4u, Max: %4u, Avg: %4u, Total samples: %lu\r\n",
min_val,
max_val,
avg,
total_samples);
}
}
// FreeRTOS Tasks
void usb_device_task(void *param) {
(void)param;
while (1) { tud_task(); }
while (1) {
tud_task();
vTaskDelay(pdMS_TO_TICKS(1));
}
}
// Задача CDC
void cdc_task(void *param) {
(void)param;
while (1) {
if (tud_cdc_connected()) {
// Отправка статистики если есть данные
if (usb_tx_buffer[0] != '\0') {
size_t len = strlen(usb_tx_buffer);
if (tud_cdc_write_available() >= len) {
tud_cdc_write(usb_tx_buffer, len);
tud_cdc_write_flush();
usb_tx_buffer[0] = '\0'; // Очищаем буфер
}
}
// Echo для тестирования
if (tud_cdc_available()) {
uint8_t buf[64];
uint32_t count = tud_cdc_read(buf, sizeof(buf));
@@ -54,21 +115,24 @@ void cdc_task(void *param) {
tud_cdc_write_flush();
}
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
// Задача LED (отдельно!)
void led_task(void *param) {
(void)param;
while (1) {
GPIOC->BSRR = GPIO_BSRR_BR13; // LED ON
vTaskDelay(pdMS_TO_TICKS(500));
vTaskDelay(pdMS_TO_TICKS(100));
GPIOC->BSRR = GPIO_BSRR_BS13; // LED OFF
vTaskDelay(pdMS_TO_TICKS(500));
vTaskDelay(pdMS_TO_TICKS(900));
}
}
// USB Reset
void force_usb_reset(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA->CRH &= ~GPIO_CRH_CNF12;
@@ -79,10 +143,12 @@ void force_usb_reset(void) {
GPIOA->CRH |= GPIO_CRH_CNF12_0;
}
// Main
int main(void) {
SystemClock_Config();
// Настройка LED
// Настройка LED (PC13)
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH &= ~GPIO_CRH_CNF13;
GPIOC->CRH |= GPIO_CRH_MODE13_1;
@@ -93,7 +159,6 @@ int main(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
// Устанавливаем приоритет USB прерываний больше 5, больше FreeRTOS
NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, 6);
NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 6);
NVIC_SetPriority(USBWakeUp_IRQn, 6);
@@ -104,6 +169,21 @@ int main(void) {
tusb_init();
// Инициализация Audio ADC
if (!audio_adc_init(audio_buffer_ready)) {
// Ошибка инициализации - быстро мигаем LED
while (1) {
GPIOC->BSRR = GPIO_BSRR_BR13;
for (volatile int i = 0; i < 100000; i++);
GPIOC->BSRR = GPIO_BSRR_BS13;
for (volatile int i = 0; i < 100000; i++);
}
}
// Запускаем захват аудио
audio_adc_start();
// Создаем задачи FreeRTOS
xTaskCreate(
usb_device_task,
"usbd",
@@ -115,9 +195,12 @@ int main(void) {
xTaskCreate(led_task, "led", 128, NULL, 1, NULL);
vTaskStartScheduler();
while (1);
}
// USB Interrupt Handlers
void USB_HP_CAN1_TX_IRQHandler(void) {
tud_int_handler(0);
}