feat(fw/health): добавлено моргание светодиода
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "audio_adc.h"
|
||||
#include "audio_processor.h" // НОВОЕ
|
||||
#include "health.h"
|
||||
#include "protocol.h"
|
||||
#include "queue.h"
|
||||
#include "stm32f1xx.h"
|
||||
@@ -18,6 +19,22 @@ void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
|
||||
}
|
||||
}
|
||||
|
||||
void vApplicationMallocFailedHook(void) {
|
||||
taskDISABLE_INTERRUPTS();
|
||||
while (1) {
|
||||
GPIOC->ODR ^= GPIO_ODR_ODR13;
|
||||
for (volatile int i = 0; i < 200000; i++) {}
|
||||
}
|
||||
}
|
||||
|
||||
static void panic_blink_forever(uint32_t delay_ms) {
|
||||
// PC13 уже сконфигурирован в main
|
||||
while (1) {
|
||||
GPIOC->ODR ^= GPIO_ODR_ODR13;
|
||||
vTaskDelay(pdMS_TO_TICKS(delay_ms));
|
||||
}
|
||||
}
|
||||
|
||||
// === Структуры данных ===
|
||||
|
||||
typedef struct {
|
||||
@@ -63,7 +80,7 @@ void audio_buffer_ready(audio_sample_t *buffer, uint32_t size) {
|
||||
buffer_counter++;
|
||||
|
||||
// Мигаем LED
|
||||
if (buffer_counter % 5 == 0) { GPIOC->ODR ^= GPIO_ODR_ODR13; }
|
||||
/* if (buffer_counter % 5 == 0) { GPIOC->ODR ^= GPIO_ODR_ODR13; } */
|
||||
|
||||
// Копируем данные (ISR должен быть быстрым)
|
||||
memcpy(processing_buffer, buffer, size * sizeof(audio_sample_t));
|
||||
@@ -89,47 +106,57 @@ void usb_device_task(void *param) {
|
||||
}
|
||||
}
|
||||
|
||||
// НОВОЕ: задача обработки FFT
|
||||
TaskHandle_t audio_process_task_handle = NULL;
|
||||
|
||||
void audio_process_task(void *param) {
|
||||
(void)param;
|
||||
|
||||
// Инициализация процессора
|
||||
if (!audio_processor_init()) {
|
||||
// Ошибка FFT init
|
||||
while (1) {
|
||||
GPIOC->ODR ^= GPIO_ODR_ODR13;
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
health_kick_watchdog();
|
||||
}
|
||||
}
|
||||
|
||||
audio_metrics_t metrics;
|
||||
|
||||
TickType_t last_wake = xTaskGetTickCount();
|
||||
const TickType_t period = pdMS_TO_TICKS(100); // 10 Hz
|
||||
|
||||
while (1) {
|
||||
// Ждём сигнала от ISR
|
||||
// 1) Ждём хотя бы один новый буфер от ISR
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
// Обработка 512 сэмплов
|
||||
// 2) Выкидываем накопившиеся уведомления, чтобы не пытаться "догонять"
|
||||
// прошлое
|
||||
while (ulTaskNotifyTake(pdTRUE, 0) > 0) {}
|
||||
|
||||
// 3) Обрабатываем самый свежий буфер (processing_buffer
|
||||
// перезаписывается в ISR)
|
||||
if (audio_processor_process_512(processing_buffer, &metrics)) {
|
||||
// Отправляем только каждый 10-й (10 Hz)
|
||||
if (buffer_counter % 10 == 0) {
|
||||
audio_metrics_packet_t packet = {
|
||||
.rms_dbfs = metrics.rms_dbfs,
|
||||
.peak_hz = metrics.peak_hz,
|
||||
.peak_mag = metrics.peak_mag,
|
||||
.clipped = metrics.clipped,
|
||||
.timestamp_ms = xTaskGetTickCount(),
|
||||
};
|
||||
xQueueSend(audio_metrics_queue, &packet, 0);
|
||||
}
|
||||
health_update_led(metrics.peak_hz, metrics.rms_dbfs);
|
||||
|
||||
audio_metrics_packet_t packet = {
|
||||
.rms_dbfs = metrics.rms_dbfs,
|
||||
.peak_hz = metrics.peak_hz,
|
||||
.peak_mag = metrics.peak_mag,
|
||||
.clipped = metrics.clipped,
|
||||
.timestamp_ms = xTaskGetTickCount(),
|
||||
};
|
||||
(void)xQueueSend(audio_metrics_queue, &packet, 0);
|
||||
}
|
||||
|
||||
health_kick_watchdog();
|
||||
|
||||
// ограничиваем частоту обработки
|
||||
vTaskDelayUntil(&last_wake, period);
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_task(void *param) {
|
||||
(void)param;
|
||||
// Buffer for the FR-1.4 packet (12 bytes)
|
||||
// Buffer for packet (12 bytes)
|
||||
uint8_t tx_buffer[PACKET_TOTAL_SIZE];
|
||||
|
||||
while (1) {
|
||||
@@ -164,16 +191,6 @@ void cdc_task(void *param) {
|
||||
}
|
||||
}
|
||||
|
||||
void led_task(void *param) {
|
||||
(void)param;
|
||||
while (1) {
|
||||
GPIOC->BSRR = GPIO_BSRR_BR13;
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
GPIOC->BSRR = GPIO_BSRR_BS13;
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
}
|
||||
}
|
||||
|
||||
void audio_init_task(void *param) {
|
||||
(void)param;
|
||||
|
||||
@@ -215,9 +232,9 @@ void force_usb_reset(void) {
|
||||
int main(void) {
|
||||
SystemClock_Config();
|
||||
|
||||
// LED
|
||||
// LED GPIO (will be managed by health_led_task)
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
|
||||
GPIOC->CRH &= ~GPIO_CRH_CNF13;
|
||||
GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);
|
||||
GPIOC->CRH |= GPIO_CRH_MODE13_1;
|
||||
|
||||
force_usb_reset();
|
||||
@@ -225,18 +242,19 @@ int main(void) {
|
||||
// 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();
|
||||
|
||||
// НОВОЕ: очередь для метрик FFT
|
||||
// Initialize watchdog BEFORE starting tasks
|
||||
health_init_watchdog();
|
||||
|
||||
// FFT queue
|
||||
audio_metrics_queue = xQueueCreate(10, sizeof(audio_metrics_packet_t));
|
||||
if (audio_metrics_queue == NULL) {
|
||||
while (1) {
|
||||
@@ -245,7 +263,7 @@ int main(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Задачи
|
||||
// Create tasks
|
||||
xTaskCreate(
|
||||
usb_device_task,
|
||||
"usbd",
|
||||
@@ -254,10 +272,10 @@ int main(void) {
|
||||
configMAX_PRIORITIES - 1,
|
||||
NULL);
|
||||
xTaskCreate(cdc_task, "cdc", 320, NULL, configMAX_PRIORITIES - 2, NULL);
|
||||
xTaskCreate(led_task, "led", 128, NULL, 1, NULL);
|
||||
xTaskCreate(audio_init_task, "audio_init", 128, NULL, 2, NULL);
|
||||
|
||||
// НОВОЕ: задача обработки FFT (высокий приоритет, большой стек для FFT)
|
||||
xTaskCreate(health_led_task, "health_led", 128, NULL, 1, NULL);
|
||||
|
||||
xTaskCreate(audio_init_task, "audio_init", 128, NULL, 2, NULL);
|
||||
xTaskCreate(
|
||||
audio_process_task,
|
||||
"audio_proc",
|
||||
@@ -266,9 +284,14 @@ int main(void) {
|
||||
configMAX_PRIORITIES - 2,
|
||||
&audio_process_task_handle);
|
||||
|
||||
if (xTaskCreate(health_led_task, "health_led", 128, NULL, 1, NULL) !=
|
||||
pdPASS) {
|
||||
panic_blink_forever(100);
|
||||
}
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
while (1);
|
||||
while (1); // Should never reach here
|
||||
}
|
||||
|
||||
// === USB Handlers ===
|
||||
|
||||
Reference in New Issue
Block a user