15
This commit is contained in:
@@ -10,6 +10,13 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* ============================================================
|
||||
* TEST MODE: Generate simulated sensor data without real hardware.
|
||||
* Set to 1 to enable test pattern generation (no sensor/DVP needed).
|
||||
* Set to 0 for normal operation with real Mini212G2 sensor.
|
||||
* ============================================================ */
|
||||
#define TEST_PATTERN_MODE 1
|
||||
|
||||
#define MAX_TCP_PAYLOAD_SIZE 10240
|
||||
uint8_t g_TxNetBuffer_A_Mem[MAX_TCP_PAYLOAD_SIZE];
|
||||
uint8_t g_TxNetBuffer_B_Mem[MAX_TCP_PAYLOAD_SIZE];
|
||||
@@ -208,9 +215,15 @@ static void task_heartbeat_entry(void *pvParameters)
|
||||
uint32_t cnt = 0;
|
||||
while (1)
|
||||
{
|
||||
#if TEST_PATTERN_MODE
|
||||
printf("[HB] %d tick=%d TEST_MODE frm=%d\r\n",
|
||||
(int)cnt++, (int)xTaskGetTickCount(),
|
||||
(int)dvp_frame_count);
|
||||
#else
|
||||
printf("[HB] %d tick=%d dvp_frm=%d row_irq=%d\r\n",
|
||||
(int)cnt++, (int)xTaskGetTickCount(),
|
||||
(int)dvp_frame_count, (int)dvp_row_irq_cnt);
|
||||
#endif
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
}
|
||||
}
|
||||
@@ -240,6 +253,94 @@ static uint8_t burst_active = 0; /* 1 = currently in burst */
|
||||
static uint8_t burst_remaining = 0; /* frames left to capture */
|
||||
static uint32_t burst_next_time_ms = 0; /* next burst frame time */
|
||||
|
||||
#if TEST_PATTERN_MODE
|
||||
/* ============================================================
|
||||
* Test Pattern Generator
|
||||
* Generates simulated 256x192 Y16 thermal images at ~10 FPS.
|
||||
* Pattern cycles through several types so all pipeline paths
|
||||
* can be exercised.
|
||||
*
|
||||
* Pattern 0: Gradient (25.00~45.00°C) — baseline, no trigger
|
||||
* Pattern 1: Hot center spot (90.00°C) — should trigger alarm
|
||||
* Pattern 2: Uniform warm (35.00°C) — no trigger
|
||||
* Pattern 3: Checkerboard with hot cells — tests ROI search
|
||||
* ============================================================ */
|
||||
#define TEST_FPS_DELAY_MS 100 /* ~10 FPS */
|
||||
#define TEMP_RAW(deg_c) ((uint16_t)((deg_c) * 100)) /* e.g. 35.00°C → 3500 */
|
||||
|
||||
static void test_fill_gradient(uint16_t *buf, uint16_t w, uint16_t h)
|
||||
{
|
||||
/* Top-to-bottom gradient: 25°C at top → 45°C at bottom */
|
||||
for (uint16_t y = 0; y < h; y++) {
|
||||
uint16_t temp = TEMP_RAW(25.0) + (uint16_t)((uint32_t)y * TEMP_RAW(20.0) / h);
|
||||
for (uint16_t x = 0; x < w; x++)
|
||||
buf[y * w + x] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_fill_hotspot(uint16_t *buf, uint16_t w, uint16_t h)
|
||||
{
|
||||
/* Background 30°C, center 32x32 block at 90°C */
|
||||
for (uint16_t y = 0; y < h; y++)
|
||||
for (uint16_t x = 0; x < w; x++)
|
||||
buf[y * w + x] = TEMP_RAW(30.0);
|
||||
uint16_t cx = w / 2, cy = h / 2;
|
||||
for (uint16_t y = cy - 16; y < cy + 16; y++)
|
||||
for (uint16_t x = cx - 16; x < cx + 16; x++)
|
||||
buf[y * w + x] = TEMP_RAW(90.0);
|
||||
}
|
||||
|
||||
static void test_fill_uniform(uint16_t *buf, uint16_t w, uint16_t h)
|
||||
{
|
||||
for (uint16_t y = 0; y < h; y++)
|
||||
for (uint16_t x = 0; x < w; x++)
|
||||
buf[y * w + x] = TEMP_RAW(35.0);
|
||||
}
|
||||
|
||||
static void test_fill_checker(uint16_t *buf, uint16_t w, uint16_t h)
|
||||
{
|
||||
/* 32x32 checkerboard: alternating 30°C and 85°C blocks */
|
||||
for (uint16_t y = 0; y < h; y++)
|
||||
for (uint16_t x = 0; x < w; x++) {
|
||||
uint8_t cell = ((y / 32) + (x / 32)) & 1;
|
||||
buf[y * w + x] = cell ? TEMP_RAW(85.0) : TEMP_RAW(30.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void task_test_pattern_entry(void *pvParameters)
|
||||
{
|
||||
(void)pvParameters;
|
||||
uint32_t frame_num = 0;
|
||||
uint8_t pattern_idx = 0;
|
||||
/* Cycle: gradient x20, hotspot x5, uniform x10, checker x5 */
|
||||
const uint8_t pattern_seq[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3};
|
||||
const uint8_t seq_len = sizeof(pattern_seq);
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint16_t *buf = (uint16_t *)FrameBuffer;
|
||||
switch (pattern_seq[pattern_idx % seq_len]) {
|
||||
case 0: test_fill_gradient(buf, SENSOR_WIDTH, SENSOR_HEIGHT); break;
|
||||
case 1: test_fill_hotspot(buf, SENSOR_WIDTH, SENSOR_HEIGHT); break;
|
||||
case 2: test_fill_uniform(buf, SENSOR_WIDTH, SENSOR_HEIGHT); break;
|
||||
case 3: test_fill_checker(buf, SENSOR_WIDTH, SENSOR_HEIGHT); break;
|
||||
}
|
||||
pattern_idx++;
|
||||
if (pattern_idx >= seq_len) pattern_idx = 0;
|
||||
|
||||
frame_num++;
|
||||
dvp_frame_count = frame_num;
|
||||
Ready_Frame_Count = frame_num;
|
||||
Frame_Ready_Flag = 1;
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(TEST_FPS_DELAY_MS));
|
||||
}
|
||||
}
|
||||
#endif /* TEST_PATTERN_MODE */
|
||||
|
||||
static void task_business_entry(void *pvParameters)
|
||||
{
|
||||
(void)pvParameters;
|
||||
@@ -253,7 +354,9 @@ static void task_business_entry(void *pvParameters)
|
||||
g_ng_off_time = 0;
|
||||
}
|
||||
|
||||
#if !TEST_PATTERN_MODE
|
||||
DVP_Task();
|
||||
#endif
|
||||
|
||||
if (Frame_Ready_Flag)
|
||||
{
|
||||
@@ -348,8 +451,13 @@ int main(void)
|
||||
for (i = 0; i < 6; i++) printf("%x ", MACAddr[i]);
|
||||
printf("\n");
|
||||
|
||||
#if TEST_PATTERN_MODE
|
||||
printf("=== TEST PATTERN MODE === No sensor/DVP hardware needed\r\n");
|
||||
/* Skip Mini212G2_Init() and DVP_Init() */
|
||||
#else
|
||||
Mini212G2_Init(); /* Configure sensor for CMOS/DVP Y16 output */
|
||||
DVP_Init();
|
||||
#endif
|
||||
TIM2_Init();
|
||||
NG_GPIO_Init();
|
||||
|
||||
@@ -377,6 +485,9 @@ int main(void)
|
||||
xTaskCreate(task_wchnet_entry, "wchnet", 512, NULL, 6, NULL);
|
||||
xTaskCreate(task_business_entry, "business", 512, NULL, 5, NULL);
|
||||
xTaskCreate(task_heartbeat_entry, "hb", 256, NULL, 3, NULL);
|
||||
#if TEST_PATTERN_MODE
|
||||
xTaskCreate(task_test_pattern_entry, "testpat", 256, NULL, 4, NULL);
|
||||
#endif
|
||||
DBG_APP("Starting scheduler\r\n");
|
||||
vTaskStartScheduler();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user