Files
sound-analyze/firmware/App/Src/main.c

215 lines
5.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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: 2 цикла ожидания для 72 MHz
FLASH->ACR = FLASH_ACR_LATENCY_2;
// 3. Настраиваем PLL: 8 MHz * 9 = 72 MHz
RCC->CFGR &= ~RCC_CFGR_PLLMULL;
RCC->CFGR |= RCC_CFGR_PLLMULL9;
RCC->CFGR |= RCC_CFGR_PLLSRC; // Источник PLL = HSE
// 4. USB делитель: 72 MHz / 1.5 = 48 MHz
RCC->CFGR &= ~RCC_CFGR_USBPRE; // USBPRE = 0 (делитель 1.5)
// 5. Включаем PLL
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
// 6. Переключаем системную частоту на PLL
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
SystemCoreClock = 72000000;
}
// 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();
vTaskDelay(pdMS_TO_TICKS(1));
}
}
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));
tud_cdc_write(buf, count);
tud_cdc_write_flush();
}
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
void led_task(void *param) {
(void)param;
while (1) {
GPIOC->BSRR = GPIO_BSRR_BR13; // LED ON
vTaskDelay(pdMS_TO_TICKS(100));
GPIOC->BSRR = GPIO_BSRR_BS13; // LED OFF
vTaskDelay(pdMS_TO_TICKS(900));
}
}
// USB Reset
void force_usb_reset(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA->CRH &= ~GPIO_CRH_CNF12;
GPIOA->CRH |= GPIO_CRH_MODE12_1;
GPIOA->BSRR = GPIO_BSRR_BR12;
for (volatile int i = 0; i < 500000; i++) __NOP();
GPIOA->CRH &= ~GPIO_CRH_MODE12;
GPIOA->CRH |= GPIO_CRH_CNF12_0;
}
// Main
int main(void) {
SystemClock_Config();
// Настройка LED (PC13)
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH &= ~GPIO_CRH_CNF13;
GPIOC->CRH |= GPIO_CRH_MODE13_1;
force_usb_reset();
// Включаем USB
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, 6);
NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 6);
NVIC_SetPriority(USBWakeUp_IRQn, 6);
NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
NVIC_EnableIRQ(USBWakeUp_IRQn);
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",
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);
}
// USB Interrupt Handlers
void USB_HP_CAN1_TX_IRQHandler(void) {
tud_int_handler(0);
}
void USB_LP_CAN1_RX0_IRQHandler(void) {
tud_int_handler(0);
}
void USBWakeUp_IRQHandler(void) {
tud_int_handler(0);
}