15
This commit is contained in:
parent
cde0bd8243
commit
49605367e9
@ -48,6 +48,10 @@ static const uint8_t CMD_SHUTTER[] =
|
||||
static const uint8_t CMD_QUERY_DIGITAL[] =
|
||||
{0x55, 0xAA, 0x07, 0x02, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x84, 0xF0};
|
||||
|
||||
/* Query: status page (simplest query, always works) */
|
||||
static const uint8_t CMD_QUERY_STATUS[] =
|
||||
{0x55, 0xAA, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x87, 0xF0};
|
||||
|
||||
/* ============================================================
|
||||
* Low-level UART helpers
|
||||
* ============================================================ */
|
||||
@ -142,8 +146,9 @@ static void Sensor_FlushRx(void)
|
||||
* ============================================================ */
|
||||
volatile uint8_t sensor_init_ok = 0;
|
||||
volatile uint8_t sensor_init_fail = 0;
|
||||
volatile uint8_t sensor_last_resp[8] = {0};
|
||||
volatile uint8_t sensor_last_resp[32] = {0};
|
||||
volatile uint8_t sensor_last_resp_len = 0;
|
||||
volatile uint8_t sensor_comm_test = 0;
|
||||
|
||||
int Mini212G2_SendCmd(const uint8_t *cmd, uint8_t len)
|
||||
{
|
||||
@ -154,7 +159,7 @@ int Mini212G2_SendCmd(const uint8_t *cmd, uint8_t len)
|
||||
int n = Sensor_ReadResp(resp, sizeof(resp), 200);
|
||||
/* Save last response for debugger inspection */
|
||||
sensor_last_resp_len = (uint8_t)n;
|
||||
for (int j = 0; j < n && j < 8; j++)
|
||||
for (int j = 0; j < n && j < 32; j++)
|
||||
sensor_last_resp[j] = resp[j];
|
||||
|
||||
if (n == ACK_LEN && memcmp(resp, ACK_PATTERN, ACK_LEN) == 0)
|
||||
@ -185,6 +190,20 @@ int Mini212G2_Init(void)
|
||||
printf("[Sensor] Waiting 3s for sensor boot...\r\n");
|
||||
Delay_Ms(3000);
|
||||
|
||||
/* === Communication test: send status query === */
|
||||
{
|
||||
uint8_t test_resp[32];
|
||||
Sensor_FlushRx();
|
||||
Sensor_SendBytes(CMD_QUERY_STATUS, sizeof(CMD_QUERY_STATUS));
|
||||
int tn = Sensor_ReadResp(test_resp, sizeof(test_resp), 500);
|
||||
sensor_last_resp_len = (uint8_t)tn;
|
||||
for (int j = 0; j < tn && j < 32; j++)
|
||||
sensor_last_resp[j] = test_resp[j];
|
||||
sensor_comm_test = (tn > 0) ? 1 : 0xFF;
|
||||
/* Breakpoint here to check sensor_comm_test and sensor_last_resp */
|
||||
}
|
||||
Delay_Ms(200);
|
||||
|
||||
printf("[Sensor] Configuring CMOS/DVP output...\r\n");
|
||||
|
||||
/* 1. Shutter compensation */
|
||||
|
||||
@ -35,8 +35,10 @@ int Mini212G2_Init(void);
|
||||
* sensor_last_resp_len: length of last response */
|
||||
extern volatile uint8_t sensor_init_ok;
|
||||
extern volatile uint8_t sensor_init_fail;
|
||||
extern volatile uint8_t sensor_last_resp[8];
|
||||
extern volatile uint8_t sensor_last_resp[32];
|
||||
extern volatile uint8_t sensor_last_resp_len;
|
||||
/* sensor_comm_test: 0=not run, 1=got response, 0xFF=no response (timeout) */
|
||||
extern volatile uint8_t sensor_comm_test;
|
||||
|
||||
#if SENSOR_UART_ENABLE
|
||||
/**
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user