This commit is contained in:
zhoujie 2026-03-14 12:19:36 +08:00
parent 15f5230095
commit d53ab96f53
5 changed files with 86 additions and 15 deletions

View File

@ -9,7 +9,8 @@ __attribute__((aligned(4))) uint8_t DMA_LineBuf1[BYTES_PER_LINE];
volatile uint8_t Line_Ready_Flag = 0; volatile uint8_t Line_Ready_Flag = 0;
volatile uint8_t *Ready_Line_Ptr = NULL; volatile uint8_t *Ready_Line_Ptr = NULL;
volatile uint32_t current_line_idx = 0; volatile uint32_t current_line_idx = 0;
static uint32_t frame_count = 0; volatile uint32_t dvp_frame_count = 0;
volatile uint32_t dvp_row_irq_cnt = 0;
extern u8 socket[]; extern u8 socket[];
extern volatile uint32_t sys_tick_ms; extern volatile uint32_t sys_tick_ms;
@ -46,6 +47,10 @@ void DVP_Init(void)
DVP_INTCfg(ENABLE, RB_DVP_IE_STR_FRM | RB_DVP_IE_ROW_DONE); DVP_INTCfg(ENABLE, RB_DVP_IE_STR_FRM | RB_DVP_IE_ROW_DONE);
DVP_Cfg(DVP_DMA_Enable, DVP_FLAG_FIFO_RESET_Disable, DVP_RX_RESET_Disable); DVP_Cfg(DVP_DMA_Enable, DVP_FLAG_FIFO_RESET_Disable, DVP_RX_RESET_Disable);
DVP->CR0 |= RB_DVP_ENABLE; DVP->CR0 |= RB_DVP_ENABLE;
printf("[DVP] Init done CR0=0x%02x CR1=0x%02x ROW=%d COL=%d\r\n",
(int)(DVP->CR0 & 0xFF), (int)(DVP->CR1 & 0xFF),
(int)DVP->ROW_NUM, (int)DVP->COL_NUM);
} }
#define PROTOCOL_HEADER_RESERVE 64 #define PROTOCOL_HEADER_RESERVE 64
@ -71,7 +76,7 @@ void DVP_Task(void)
if (idx == SENSOR_HEIGHT - 1) if (idx == SENSOR_HEIGHT - 1)
{ {
Frame_Ready_Flag = 1; Frame_Ready_Flag = 1;
Ready_Frame_Count = frame_count; Ready_Frame_Count = dvp_frame_count;
} }
} }
} }
@ -83,12 +88,13 @@ void DVP_IRQHandler(void)
{ {
DVP->IFR = RB_DVP_IF_STR_FRM; DVP->IFR = RB_DVP_IF_STR_FRM;
current_line_idx = 0; current_line_idx = 0;
frame_count++; dvp_frame_count++;
} }
if (DVP->IFR & RB_DVP_IF_ROW_DONE) if (DVP->IFR & RB_DVP_IF_ROW_DONE)
{ {
DVP->IFR = RB_DVP_IF_ROW_DONE; DVP->IFR = RB_DVP_IF_ROW_DONE;
Ready_Line_Ptr = (DVP->CR1 & RB_DVP_BUF_TOG) ? DMA_LineBuf0 : DMA_LineBuf1; Ready_Line_Ptr = (DVP->CR1 & RB_DVP_BUF_TOG) ? DMA_LineBuf0 : DMA_LineBuf1;
dvp_row_irq_cnt++;
current_line_idx++; current_line_idx++;
Line_Ready_Flag = 1; Line_Ready_Flag = 1;
} }

View File

@ -12,6 +12,8 @@
extern volatile uint8_t Line_Ready_Flag; extern volatile uint8_t Line_Ready_Flag;
extern volatile uint8_t *Ready_Line_Ptr; extern volatile uint8_t *Ready_Line_Ptr;
extern volatile uint32_t current_line_idx; extern volatile uint32_t current_line_idx;
extern volatile uint32_t dvp_frame_count;
extern volatile uint32_t dvp_row_irq_cnt;
void DVP_Init(void); void DVP_Init(void);
void DVP_Task(void); void DVP_Task(void);

View File

@ -176,8 +176,8 @@ void qdx_port_sock_recv_notify(uint8_t sockid)
total += len; total += len;
if (err != WCHNET_ERR_SUCCESS) break; if (err != WCHNET_ERR_SUCCESS) break;
} }
DBG_PORT("recv_notify sock%d: %lu bytes, ring=%d\r\n", DBG_PORT("recv_notify sock%d: %u bytes, ring=%u\r\n",
sockid, total, ring_available(&ctx->rx_ring)); sockid, (unsigned)total, (unsigned)ring_available(&ctx->rx_ring));
/* Wake blocking recv thread */ /* Wake blocking recv thread */
xSemaphoreGive(ctx->rx_sem); xSemaphoreGive(ctx->rx_sem);
} }
@ -268,8 +268,8 @@ int8_t qdx_port_thread_create(const char *name, qdx_thread_entry_t entry,
BaseType_t ret = xTaskCreate((TaskFunction_t)entry, name, BaseType_t ret = xTaskCreate((TaskFunction_t)entry, name,
(uint16_t)stack_words, arg, (uint16_t)stack_words, arg,
(UBaseType_t)priority, NULL); (UBaseType_t)priority, NULL);
DBG_PORT("thread_create \"%s\" stack=%lu pri=%d -> %s\r\n", DBG_PORT("thread_create \"%s\" stack=%d pri=%d -> %s\r\n",
name, stack_words, priority, (ret == pdPASS) ? "OK" : "FAIL"); name, (int)stack_words, (int)priority, (ret == pdPASS) ? "OK" : "FAIL");
return (ret == pdPASS) ? 0 : -1; return (ret == pdPASS) ? 0 : -1;
} }
@ -343,14 +343,14 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port)
uint32_t elapsed = (xTaskGetTickCount() - t0) * portTICK_PERIOD_MS; uint32_t elapsed = (xTaskGetTickCount() - t0) * portTICK_PERIOD_MS;
if (sem_ret != pdTRUE) { if (sem_ret != pdTRUE) {
DBG_PORT("connect_sem TIMEOUT after %lu ms -> %d.%d.%d.%d:%d\r\n", DBG_PORT("connect_sem TIMEOUT after %d ms -> %d.%d.%d.%d:%d\r\n",
elapsed, dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3], port); (int)elapsed, dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3], port);
DBG_PORT(" ctx->connected=%d wchnet_id=%d\r\n", ctx->connected, wchnet_id); DBG_PORT(" ctx->connected=%d wchnet_id=%d\r\n", ctx->connected, wchnet_id);
WCHNET_SocketClose(wchnet_id, 0); WCHNET_SocketClose(wchnet_id, 0);
free_sock_ctx(ctx); free_sock_ctx(ctx);
return NULL; return NULL;
} }
DBG_PORT("connect_sem got after %lu ms, connected=%d\r\n", elapsed, ctx->connected); DBG_PORT("connect_sem got after %d ms, connected=%d\r\n", (int)elapsed, ctx->connected);
if (!ctx->connected) { if (!ctx->connected) {
WCHNET_SocketClose(wchnet_id, 0); WCHNET_SocketClose(wchnet_id, 0);

View File

@ -141,7 +141,6 @@ static void tcp_send_handshake(TcpStreamCtx_t *ctx) {
} }
static void tcp_send_heartbeat(TcpStreamCtx_t *ctx) { static void tcp_send_heartbeat(TcpStreamCtx_t *ctx) {
DBG_LOGIC("[%s] heartbeat\r\n", ctx->label);
uint8_t payload[6]; uint8_t payload[6];
qdx_write_u32_le(payload + 0, qdx_port_get_tick_ms()); qdx_write_u32_le(payload + 0, qdx_port_get_tick_ms());
payload[4] = 10; /* Placeholder CpuLoad */ payload[4] = 10; /* Placeholder CpuLoad */

View File

@ -58,8 +58,16 @@ void OnDetectionResult(uint32_t frameNumber, uint8_t resultStatus)
(void)frameNumber; (void)frameNumber;
/* resultStatus: 0 = NG, 1 = OK */ /* resultStatus: 0 = NG, 1 = OK */
if (resultStatus == 0) { if (resultStatus == 0) {
ConfigCommon_t tmp_common;
Config2D_t tmp_cfg2d;
Config1D_t tmp_cfg1d;
uint32_t pulse_ms = NG_PULSE_MS; /* fallback default */
if (TcpLogic_GetLatestConfig(&tmp_common, &tmp_cfg2d, &tmp_cfg1d) == 0
&& tmp_cfg2d.NGioDelay > 0) {
pulse_ms = tmp_cfg2d.NGioDelay;
}
GPIO_SetBits(NG_GPIO_PORT, NG_GPIO_PIN); GPIO_SetBits(NG_GPIO_PORT, NG_GPIO_PIN);
g_ng_off_time = sys_tick_ms + NG_PULSE_MS; g_ng_off_time = sys_tick_ms + pulse_ms;
} }
} }
@ -199,7 +207,9 @@ static void task_heartbeat_entry(void *pvParameters)
uint32_t cnt = 0; uint32_t cnt = 0;
while (1) while (1)
{ {
printf("[HB] %lu tick=%lu\r\n", cnt++, xTaskGetTickCount()); 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);
vTaskDelay(pdMS_TO_TICKS(2000)); vTaskDelay(pdMS_TO_TICKS(2000));
} }
} }
@ -222,6 +232,13 @@ static void task_wchnet_entry(void *pvParameters)
/* ============================================================ /* ============================================================
* RTOS Task: Business logic (DVP + preprocess + send) * RTOS Task: Business logic (DVP + preprocess + send)
* ============================================================ */ * ============================================================ */
/* ============================================================
* Burst capture state machine
* ============================================================ */
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 */
static void task_business_entry(void *pvParameters) static void task_business_entry(void *pvParameters)
{ {
(void)pvParameters; (void)pvParameters;
@ -247,15 +264,62 @@ static void task_business_entry(void *pvParameters)
raw_img.Height = SENSOR_HEIGHT; raw_img.Height = SENSOR_HEIGHT;
raw_img.FrameNumber = Ready_Frame_Count; raw_img.FrameNumber = Ready_Frame_Count;
if (Preprocess_CheckInternalTrigger2D(&raw_img) == 1) if (burst_active)
{ {
/* Burst mode: wait for interval, then capture & send */
if (sys_tick_ms >= burst_next_time_ms)
{
PreprocessResult_t meta;
TcpTxBuffer_t *tx_buf = use_buffer_A ? &g_TxNetBuffer_A : &g_TxNetBuffer_B;
use_buffer_A = !use_buffer_A;
tx_buf->ValidPayloadLen = 0;
if (Preprocess_Execute(&raw_img, tx_buf, &meta) == 0)
{
TcpLogic_BuildAndSendTemperatureFrame(tx_buf, &meta, 0x01, 1);
}
burst_remaining--;
if (burst_remaining == 0) {
burst_active = 0;
DBG_APP("Burst complete\r\n");
} else {
/* Read interval from config */
ConfigCommon_t tc; Config2D_t t2; Config1D_t t1;
uint16_t interval_ms = 0;
if (TcpLogic_GetLatestConfig(&tc, &t2, &t1) == 0)
interval_ms = t2.TriggerInternalIntervalMs;
burst_next_time_ms = sys_tick_ms + interval_ms;
}
}
}
else if (Preprocess_CheckInternalTrigger2D(&raw_img) == 1)
{
/* Trigger hit! Start burst: this frame is frame #0 */
PreprocessResult_t meta; PreprocessResult_t meta;
TcpTxBuffer_t *tx_buf = use_buffer_A ? &g_TxNetBuffer_A : &g_TxNetBuffer_B; TcpTxBuffer_t *tx_buf = use_buffer_A ? &g_TxNetBuffer_A : &g_TxNetBuffer_B;
use_buffer_A = !use_buffer_A; use_buffer_A = !use_buffer_A;
tx_buf->ValidPayloadLen = 0;
if (Preprocess_Execute(&raw_img, tx_buf, &meta) == 0) if (Preprocess_Execute(&raw_img, tx_buf, &meta) == 0)
{ {
TcpLogic_BuildAndSendTemperatureFrame(tx_buf, &meta, 1, 1); TcpLogic_BuildAndSendTemperatureFrame(tx_buf, &meta, 0x01, 1);
}
/* Determine burst count from config */
ConfigCommon_t tc; Config2D_t t2; Config1D_t t1;
uint8_t total_burst = 1;
uint16_t interval_ms = 0;
if (TcpLogic_GetLatestConfig(&tc, &t2, &t1) == 0) {
if (t2.TriggerBurstCount > 1)
total_burst = t2.TriggerBurstCount;
interval_ms = t2.TriggerInternalIntervalMs;
}
if (total_burst > 1) {
burst_active = 1;
burst_remaining = total_burst - 1; /* frame #0 already sent */
burst_next_time_ms = sys_tick_ms + interval_ms;
DBG_APP("Burst start: %d frames, interval=%d ms\r\n",
(int)total_burst, (int)interval_ms);
} }
} }
} }