2026-03-13 22:42:57 +08:00

100 lines
3.3 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 "dvp.h"
#include "ch32v30x_dvp.h"
#include "eth_driver.h"
#include "string.h"
__attribute__((aligned(4))) uint8_t DMA_LineBuf0[BYTES_PER_LINE];
__attribute__((aligned(4))) uint8_t DMA_LineBuf1[BYTES_PER_LINE];
volatile uint8_t Line_Ready_Flag = 0;
volatile uint8_t *Ready_Line_Ptr = NULL;
volatile uint32_t current_line_idx = 0;
static uint32_t frame_count = 0;
extern u8 socket[];
void DVP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DVP, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DVP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DVP_Cfg(DVP_DMA_Disable, DVP_FLAG_FIFO_RESET_Enable, DVP_RX_RESET_Enable);
DVP_Mode(RB_DVP_D8_MOD, Video_Mode);
DVP->CR0 &= ~(RB_DVP_P_POLAR | RB_DVP_V_POLAR | RB_DVP_H_POLAR);
DVP->DMA_BUF0 = (uint32_t)DMA_LineBuf0;
DVP->DMA_BUF1 = (uint32_t)DMA_LineBuf1;
DVP->ROW_NUM = 1;
DVP->COL_NUM = BYTES_PER_LINE;
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->CR0 |= RB_DVP_ENABLE;
}
void DVP_Task(void)
{
if (!Line_Ready_Flag) return;
uint8_t *line = (uint8_t *)Ready_Line_Ptr;
uint32_t idx = current_line_idx;
Line_Ready_Flag = 0;
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD> socket <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (idx < SENSOR_HEIGHT && socket[0] != 0xFF)
{
/* 4<>ֽ<EFBFBD><D6BD><EFBFBD>ͷ<EFBFBD><CDB7>֡<EFBFBD><D6A1>(2B) + <20>к<EFBFBD>(2B) */
uint8_t hdr[4] = {
(frame_count >> 8) & 0xFF, frame_count & 0xFF,
(idx >> 8) & 0xFF, idx & 0xFF
};
u32 len = 4;
WCHNET_SocketSend(socket[0], hdr, &len);
len = BYTES_PER_LINE;
WCHNET_SocketSend(socket[0], line, &len);
/* ÿ֡<C3BF><D6A1>0<EFBFBD>д<EFBFBD>ӡһ<D3A1>Σ<EFBFBD>ȷ<EFBFBD><C8B7>֡<EFBFBD>ź<EFBFBD>socket״̬ */
if (idx == 0)
printf("[DVP] frame=%lu socket=%d\r\n", frame_count, socket[0]);
}
else if (idx == 0 && socket[0] == 0xFF)
{
/* socket δ<><CEB4><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʾ */
printf("[DVP] frame=%lu waiting for TCP...\r\n", frame_count);
}
memset(line, 0, BYTES_PER_LINE);
}
void DVP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DVP_IRQHandler(void)
{
if (DVP->IFR & RB_DVP_IF_STR_FRM)
{
DVP->IFR = RB_DVP_IF_STR_FRM;
current_line_idx = 0;
frame_count++;
}
if (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;
current_line_idx++;
Line_Ready_Flag = 1;
}
}