从SOD到OOD(整板资源管理,system manager,成员函数定义,整板初始化相关)

整板硬件初始化相关。
1)构建函数

SystemManager::SystemManager() :
	xcmos_(&cam_uart_, &sys_timer_),
	xmotor_(&mcu_uart_, this),
	xhost_(&host_uart_, this),
	xaf_(this),
	xaec_(this),
	xin_(SYS_IN_0_REGS_ADDR, 0x1000),
	xout_(SYS_OUT_0_REGS_ADDR, 0x1000),
	xbayer_write_(BAYER_IP_REGS_ADDR, 0x1000),
	xbayer_video_(VIDEO_IP_REGS_ADDR, 0x1000),
	xbayer_photo_(PHOTO_IP_REGS_ADDR, 0x1000),
	xcrop_(CROP_ACCL_REGS_ADDR, 0x1000),
	xaf_accl_(AUTO_FOCUS_REGS_ADDR, 0x1000),
//	xinfo_(RGB_INFO_REGS_ADDR, 0x1000),
	xclahe_(CLAHE_ACCL_REGS_ADDR, 0x1000),
	boot_state_(0),
	state_timestamp_(0),
	debug_mode_(0)
{
	max_dzoom_scale_ = 2.581;
	min_dzoom_scale_ = 1.0;
	video_frame_count_ = 0;
	sensor_frame_count_ = 0;
	focus_motor_reach_ = 0;
	photo_stamp_ = 0;
	photo_over_mode_ = 0;
	zoom_speed_ = 1;
	dehazing_mode_ = 0;
	hdr_mode_ = 0;
	zoom_status_ = 0;

	brightness_mode_ = 0;
	brightness_value_ = 0;
	contrast_mode_ = 0;
	contrast_value_ = 0;
	saturation_mode_ = 1;
	saturation_value_ = 22000;
	awb_mode_ = 0;
	focus_radio_ = 1024;
}

构建函数,负责填充各个成员数据。

2)INTC初始化

int SystemManager::intc_init()
{
	int ret;
	XIntc* intc = &intc_;

	/*
	 * Initialize the interrupt controller driver so that it is ready to
	 * use.
	 */
	ret = XIntc_Initialize(intc, 0);
	if (ret != XST_SUCCESS) {
		return -1;
	}


	/*
	 * Connect a device driver handler that will be called when an interrupt
	 * for the device occurs, the device driver handler performs the
	 * specific interrupt processing for the device.
	 */
	ret = XIntc_Connect(intc, HOST_UART_IRQ_ID, (XInterruptHandler)uart_lite_isr_handle, (void *)&host_uart_);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	ret = XIntc_Connect(intc, MCU_UART_IRQ_ID, (XInterruptHandler)uart_lite_isr_handle, (void *)&mcu_uart_);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	ret = XIntc_Connect(intc, CAM_UART_IRQ_ID, (XInterruptHandler)uart_lite_isr_handle, (void *)&cam_uart_);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	ret = XIntc_Connect(intc, SYS_FLASH_IRQ_ID, (XInterruptHandler)XSpi_InterruptHandler, (void *)&sys_flash_.spi);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	ret = XIntc_Connect(intc, FOCUS_MOTOR_IRQ_ID, (XInterruptHandler)focus_motor_isr_handle, (void *)this);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	ret = XIntc_Connect(intc, RGB_INFO_IRQ_ID, (XInterruptHandler)video_isr_handle, (void *)this);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	ret = XIntc_Connect(intc, SENSOR_TRIGGER_IRQ_ID, (XInterruptHandler)trigger_isr_handle, (void *)this);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	ret = XIntc_Connect(intc, TIME_LOOP_IRQ_ID, (XInterruptHandler)time_loop_isr_handle, (void *)this);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	/*
	 * Start the interrupt controller such that interrupts are enabled for
	 * all devices that cause interrupts, specific real mode so that
	 * the UartLite can cause interrupts through the interrupt controller.
	 */
	ret = XIntc_Start(intc, XIN_REAL_MODE);
	if (ret != XST_SUCCESS) {
		return -1;
	}

	/*
	 * Enable the interrupt for the UartLite device.
	 */
	XIntc_Enable(intc, HOST_UART_IRQ_ID);
	XIntc_Enable(intc, MCU_UART_IRQ_ID);
	XIntc_Enable(intc, CAM_UART_IRQ_ID);
	XIntc_Enable(intc, SYS_FLASH_IRQ_ID);
	XIntc_Enable(intc, FOCUS_MOTOR_IRQ_ID);
	XIntc_Enable(intc, SENSOR_TRIGGER_IRQ_ID);
	XIntc_Enable(intc, TIME_LOOP_IRQ_ID);
	/*
	 * Initialize the exception table.
	 */
	Xil_ExceptionInit();

	/*
	 * Register the interrupt controller handler with the exception table.
	 */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler, intc);

	/*
	 * #define XIL_EXCEPTION_ID_UNALIGNED_ACCESS     1U
	#define XIL_EXCEPTION_ID_ILLEGAL_OPCODE       2U
	#define XIL_EXCEPTION_ID_M_AXI_I_EXCEPTION    3U
	#define XIL_EXCEPTION_ID_IPLB_EXCEPTION       3U
	#define XIL_EXCEPTION_ID_M_AXI_D_EXCEPTION    4U
	#define XIL_EXCEPTION_ID_DPLB_EXCEPTION       4U
	#define XIL_EXCEPTION_ID_DIV_BY_ZERO          5U
	#define XIL_EXCEPTION_ID_FPU                  6U
	#define XIL_EXCEPTION_ID_STACK_VIOLATION      7U
	 */

	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_UNALIGNED_ACCESS, (Xil_ExceptionHandler)exception_unaligned_access_handle, (void *)this);
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_ILLEGAL_OPCODE, (Xil_ExceptionHandler)exception_illegal_opcode_handle, (void *)this);
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_M_AXI_D_EXCEPTION, (Xil_ExceptionHandler)exception_M_AXI_D_handle, (void *)this);
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_DIV_BY_ZERO, (Xil_ExceptionHandler)exception_div_by_zero_handle, (void *)this);
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_FPU, (Xil_ExceptionHandler)exception_fpu_handle, (void *)this);
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_STACK_VIOLATION, (Xil_ExceptionHandler)exception_stack_violation_handle, (void *)this);


	/*
	 * Enable exceptions.
	 */
	Xil_ExceptionEnable();

	return 0;
}



整个INTC的初始化过程,可以参考BSP中提供的各个example中提供的代码。
这里需要注意的就是,根据我们整板上的中断的配置,进行多个xintc_connect操作。
也可以根据需要,进行多个exception的register操作。
对于xinc_connect相关的interrupt handler,如下:

void focus_motor_isr_handle(SystemManager* sys)
{
	XIntc* xintc = &sys->intc_;

	//关闭中断
	XIntc_Disable(xintc, FOCUS_MOTOR_IRQ_ID);

	if (sys->boot_state_) {
		//读取标志
		sys->focus_motor_reach_ = 1;
	}

	//打开中断
	XIntc_Enable(xintc, FOCUS_MOTOR_IRQ_ID);
}

void video_isr_handle(SystemManager* sys)
{
	static u32 count = 0;
	XIntc* xintc = &sys->intc_;
	AxiLiteIn* xin = &sys->xin_;
	AutoExpGain* xaec = &sys->xaec_;
	AutoFocus* xaf = &sys->xaf_;
	AutoFocusAccl* xaf_accl = &sys->xaf_accl_;

	//关闭中断
	XIntc_Disable(xintc, RGB_INFO_IRQ_ID);

	if (sys->boot_state_) {
		//读取清晰度评价
		xaf->current_clarity_ = xaf_accl->get_clarity_value();
		//帧计数
		sys->video_frame_count_++;
		//读取RGB分块均值数据
		xin->get_rgb_win_sum(xaec->win_sum_);
		u32 lum_level = xaec->calc_lum_level();
		//防止亮度震荡
		const u32 scale = 900;
		xaec->lum_level_ = lum_level;//(scale * lum_level + (1024 - scale) * xaec->lum_level_) / 1024;

		count++;
		if (count >= 3) {
			count = 0;
		}
	}
	
	//打开中断
	XIntc_Enable(xintc, RGB_INFO_IRQ_ID);
}

void trigger_isr_handle(SystemManager* sys)
{
	XIntc* xintc = &sys->intc_;
	AxiLiteIn* xin = &sys->xin_;
	AutoExpGain* xaec = &sys->xaec_;
	AutoFocus* xaf = &sys->xaf_;
	AutoFocusAccl* xaf_accl = &sys->xaf_accl_;

	//关闭中断
	XIntc_Disable(xintc, SENSOR_TRIGGER_IRQ_ID);

	if (sys->boot_state_) {
		//设置数字增益
		sys->xcmos_.set_digital_gain(sys->xaec_.gain_, 0);
		//读取亮度均值
		u32 bayer_sum = xin->get_bayer_sum();
		u32 bayer_cnt = xin->get_bayer_cnt();
		u32 bayer_aver = (bayer_cnt == 0) ? 0 : (bayer_sum / bayer_cnt);
		xaec->lum_level_ = bayer_aver;
		//读取清晰度评价
		xaf->current_clarity_ = xaf_accl->get_clarity_value();
		//帧计数
		sys->sensor_frame_count_++;
	}
	
	//打开中断
	XIntc_Enable(xintc, SENSOR_TRIGGER_IRQ_ID);
}

void sensor_isr_handle(SystemManager* sys)
{
	XIntc* xintc = &sys->intc_;
	AxiLiteIn* xin = &sys->xin_;
	AutoExpGain* xaec = &sys->xaec_;

	//关闭中断
	XIntc_Disable(xintc, SENSOR_TRIGGER_IRQ_ID);

	if (sys->boot_state_) {
		//读取亮度均值
		u32 bayer_sum = xin->get_bayer_sum();
		u32 bayer_cnt = xin->get_bayer_cnt();
		u32 bayer_aver = (bayer_cnt == 0) ? 0 : (bayer_sum / bayer_cnt);
		xaec->lum_level_ = bayer_aver;
		//帧计数
		sys->sensor_frame_count_++;
	}

	//打开中断
	XIntc_Enable(xintc, SENSOR_TRIGGER_IRQ_ID);
}

void time_loop_isr_handle(SystemManager* sys)
{
	XIntc* xintc = &sys->intc_;

	//关闭中断
	XIntc_Disable(xintc, TIME_LOOP_IRQ_ID);

	if (sys->boot_state_) {
		//检查系统定时器
		u32 now_timestamp = sys->get_timestamp();
		if ((sys->state_timestamp_ != 0) && (sys->state_timestamp_ == now_timestamp)) {
			syslog("system timer is stop: timestamp=%u!!!!\r\n", now_timestamp);
		}
		sys->state_timestamp_ = now_timestamp;
	}

	//打开中断
	XIntc_Enable(xintc, TIME_LOOP_IRQ_ID);
}

这些callback,传入的参数callbackref,都是一个systemmanager对象,它是拥有最大索引范围的对象,以它为callbackref,是最合适的。

对于exception_register相关的exceptionhandler,如下:

void exception_unaligned_access_handle(void *arg)
{
	syslog("exception_unaligned_access_handle\r\n");
}

void exception_illegal_opcode_handle(void *arg)
{
	syslog("exception_illegal_opcode_handle\r\n");
}

void exception_M_AXI_D_handle(void *arg)
{
	syslog("exception_M_AXI_D_handle\r\n");
}

void exception_div_by_zero_handle(void *arg)
{
	syslog("exception_div_by_zero_handle\r\n");
}

void exception_fpu_handle(void *arg)
{
	syslog("exception_fpu_handle\r\n");
}

void exception_stack_violation_handle(void *arg)
{
	syslog("exception_stack_violation_handle\r\n");
}

3)sensor_init

void SystemManager::sensor_init()
{
	u32 value;

	xcmos_.set_aoi_hsize(sensor_width_);
	xcmos_.set_aoi_vsize(sensor_height_);
	xcmos_.set_aoi_hoff(0);
	xcmos_.set_aoi_voff(480);
	xcmos_.set_pixel_clock_rate(110);
	xcmos_.set_fixed_frame_period(33333);
	xcmos_.set_fixed_frame_period_en(1);


	//最大增益

	xcmos_.set_digital_gain(1024);
	xcmos_.set_anglog_gain(1);
#if SENSOR_TRIGGER_ENABLE
	xcmos_.set_ignore_next_trigger(1);
	xcmos_.set_trigger_edge_selector(0);
	xcmos_.set_trigger_input(2);
	xcmos_.set_trigger_enable(1);
	xcmos_.set_exposure_mode(1);
	xout_.set_exposure_time(15000);
#else
	xcmos_.set_trigger_enable(0);
	xcmos_.set_exposure_mode(2);
	xcmos_.set_exposure_time(15000);
#endif

	//打开自动曝光
	xcmos_.set_aec_en(0);
	//打开自动增益
	xcmos_.set_agc_en(0);

	u32 current_hsize = 0, current_vsize = 0;
	u32 max_hsize = 0, max_vsize = 0;

}

这里主要是调用xcmos_成员对象的操作集完成需要的操作。
关于xcmos这个类,后面再讲。

4)fpga_isp_init

void SystemManager::fpga_isp_init()
{
	xout_.set_ccm_mode(1);
	xout_.set_awb_mode(1);
	xout_.set_awb_Auto_en(1);
	xout_.set_awb_TL84_en(0);
	xout_.set_awb_CWF_en(0);
	xout_.set_awb_A_light_en(0);

	xout_.set_brightness_mode(brightness_mode_);
	xout_.set_brightness_value((u16)brightness_value_);

	xout_.set_contrast_mode(contrast_mode_);
	xout_.set_contrast_value((u16)contrast_value_);

	xout_.set_saturation_mode(saturation_mode_);
	xout_.set_saturation_value((u16)saturation_value_);

	xout_.set_sharpness_mode(0);
	xout_.set_sharp_shold(800);
	xout_.set_sharpness_k1(2);
	xout_.set_sharpness_k2(2);

	set_cursor_x(video_width_ / 2);
	set_cursor_y(video_height_ / 2);

	xout_.set_rgbyuv_sw(1);
	xout_.set_yuv_mode(0);
	xout_.set_color_mode(0);
	//测试图像
	xout_.set_tpg_en(0);
	xout_.set_tpg_mode(1);

	xout_.set_photo_cmd(0);
	xout_.set_photo_hcnt_max(1);
	xout_.set_photo_vcnt_max(100000000);
	xout_.set_photo_mode(0);
	usleep(1000);
	xout_.set_photo_mode(1);

}

这里主要是调用xout_对象的操作集,完成需要的操作。
AXILITE_OUT这个类,如前所述。
其中有几个函数需要特别说明,
set_cursor_x,set_cursor_y,这两个函数,是为了进一步封装操作,而设计的成员函数,所以这里看到,其调用形式,并不是“对象名索引成员函数名”的形式,形如xout_.xxx()的形式,由成员索引操作符(.)来连接左侧的对象名和右侧的成员函数名。
在书写上,没有前缀对象名,而是函数直接调用的形式。
而usleep,这个函数,是BSP提供的函数,这是全局函数,并不属于某个特定的类对象,所以,也是传统的函数直接调用的形式。

void SystemManager::set_cursor_x(int value) {
		const int w = 40;
		const int minx = w;
		const int maxx = video_width_ - w;

		value = (value < minx) ? minx : ((value > maxx) ? maxx : value);
		cursor_x_ = value;

		xout_.set_cursor_x(cursor_x_);
		xout_.set_cursor_en(1);
		usleep(10);
		xout_.set_cursor_en(0);
	}

void SystemManager::set_cursor_y(int value) {
		const int h = 40;
		const int miny = h;
		const int maxy = video_height_ - h;

		value = (value < miny) ? miny : ((value > maxy) ? maxy : value);
		cursor_y_ = value;

		xout_.set_cursor_y(cursor_y_);
		xout_.set_cursor_en(1);
		usleep(10);
		xout_.set_cursor_en(0);
	}

可以看出,这两个成员函数,是为了增强可读性,提供更好的封装,将一些操作进行了封装。

5)hls_isp_init

void SystemManager::hls_isp_init()
{
	xbayer_write_.set_ddr_base(ddr_base_);
	xbayer_write_.set_width(sensor_width_);
	xbayer_write_.set_height(sensor_height_);
	xbayer_write_.set_param(0, 0, sensor_width_, sensor_height_);

	xbayer_video_.set_ddr_base(ddr_base_);
	xbayer_video_.set_sensor_width(sensor_width_);
	xbayer_video_.set_sensor_height(sensor_height_);
	xbayer_video_.set_delay_frame(2);
	xbayer_video_.set_param(0, 0, 0, sensor_width_, sensor_height_, 3, video_align_width_, video_align_height_);

	set_dzoom_scale(max_dzoom_scale_);
	set_flip_mode(0);

	xbayer_photo_.set_ddr_base(ddr_base_);
	xbayer_photo_.set_width(sensor_width_);
	xbayer_photo_.set_height(sensor_height_);
	xbayer_photo_.set_param(photo_width_, photo_height_, sensor_width_, sensor_height_);

	xclahe_.set_width(video_align_width_);
	xclahe_.set_height(video_align_height_);
	xclahe_.set_limit_th(80);
	xclahe_.set_scale_th(2);
	xclahe_.set_mode(1);

	xcrop_.set_crop_x((video_align_width_ - video_width_) / 2);
	xcrop_.set_crop_y((video_align_height_ - video_height_) / 2);
	xcrop_.set_crop_width(video_width_);
	xcrop_.set_crop_height(video_height_);
	xcrop_.set_width(video_align_width_);
	xcrop_.set_height(video_align_height_);

	int af_roi_width = 1024;
	int af_roi_height = 512;
	int af_roi_x = (video_align_width_ - af_roi_width) / 2;
	int af_roi_y = (video_align_height_ - af_roi_height) / 2;
	xaf_accl_.set_roi_x(af_roi_x);
	xaf_accl_.set_roi_y(af_roi_y);
	xaf_accl_.set_roi_width(af_roi_width);
	xaf_accl_.set_roi_height(af_roi_height);
	xaf_accl_.set_width(video_align_width_);
	xaf_accl_.set_height(video_align_height_);
}

这里主要是调用各个类对象中定义的操作集,完成需要的操作。
这几个类,如前所述。

其中有几个函数需要特别说明,
set_dzoom_scale,set_flip_mode,这两个函数,是为了进一步封装操作,而设计的成员函数,所以这里看到,其调用形式,并不是“对象名索引成员函数名”的形式,形如xclahe_.xxx()的形式,由成员索引操作符(.)来连接左侧的对象名和右侧的成员函数名。
在书写上,没有前缀对象名,而是函数直接调用的形式。
而usleep,这个函数,是BSP提供的函数,这是全局函数,并不属于某个特定的类对象,所以,也是传统的函数直接调用的形式。

void SystemManager::set_dzoom_scale(float value) {
		dzoom_scale_ = value;

		u32 align_width = (u32)((video_align_width_ / video_align_wsize_ / 2) * dzoom_scale_) * video_align_wsize_ * 2;
		if (align_width > sensor_width_) {
			align_width = sensor_width_;
		}
		float align_scale = align_width / ((float)video_align_width_);

		u32 crop_width = xbayer_video_.check_width(align_width);
		u32 crop_height = xbayer_video_.check_height(video_align_height_ * align_scale);
		u32 crop_x = xbayer_video_.check_x((sensor_width_ - crop_width) / 2);
		u32 crop_y = xbayer_video_.check_y((sensor_height_ - crop_height) / 2);

		xbayer_video_.set_param(flip_mode_, crop_x, crop_y, crop_width, crop_height, bayer_mode_, video_align_width_, video_align_height_);
	}

void SystemManager::set_flip_mode(int value) {
		switch(value)
		{
			case 0://正常显示
			{
				flip_mode_ = 0;
				bayer_mode_ = 3;
				xbayer_video_.set_param(flip_mode_, xbayer_video_.crop_x_, xbayer_video_.crop_y_, xbayer_video_.crop_width_, xbayer_video_.crop_height_, bayer_mode_, xbayer_video_.dst_width_, xbayer_video_.dst_height_);
			}break;
			case 1://上下翻转
			{
				flip_mode_ = 1;
				bayer_mode_ = 1;
				xbayer_video_.set_param(flip_mode_, xbayer_video_.crop_x_, xbayer_video_.crop_y_, xbayer_video_.crop_width_, xbayer_video_.crop_height_, bayer_mode_, xbayer_video_.dst_width_, xbayer_video_.dst_height_);
			}break;
			case 2://左右翻转
			{
				flip_mode_ = 2;
				bayer_mode_ = 3;
				xbayer_video_.set_param(flip_mode_, xbayer_video_.crop_x_, xbayer_video_.crop_y_, xbayer_video_.crop_width_, xbayer_video_.crop_height_, bayer_mode_, xbayer_video_.dst_width_, xbayer_video_.dst_height_);
			}break;
			case 3://上下左右翻转
			{
				flip_mode_ = 3;
				bayer_mode_ = 1;
				xbayer_video_.set_param(flip_mode_, xbayer_video_.crop_x_, xbayer_video_.crop_y_, xbayer_video_.crop_width_, xbayer_video_.crop_height_, bayer_mode_, xbayer_video_.dst_width_, xbayer_video_.dst_height_);
			}break;
			default:
				break;
		}
	}

可以看出,这两个成员函数,是为了增强可读性,提供更好的封装,将一些操作进行了封装。

6)hls_isp_start

void SystemManager::hls_isp_start()
{
	xbayer_write_.set_ap_auto_restart_value(1);
	xbayer_write_.set_ap_start_value(1);

	xbayer_video_.set_ap_auto_restart_value(1);
	xbayer_video_.set_ap_start_value(1);

	xbayer_photo_.set_ap_auto_restart_value(1);
	xbayer_photo_.set_ap_start_value(1);

	xclahe_.set_ap_auto_restart_value(1);
	xclahe_.set_ap_start_value(1);

	xcrop_.set_ap_auto_restart_value(1);
	xcrop_.set_ap_start_value(1);

	xaf_accl_.set_ap_auto_restart_value(1);
	xaf_accl_.set_ap_start_value(1);
}

7)vtc_start

void SystemManager::vtc_start()
{
	//video_crop
	xout_.set_video_align_width(video_align_width_);
	xout_.set_video_align_height(video_align_height_);
	xout_.set_video_width(video_width_);
	xout_.set_video_height(video_height_);
	xout_.set_video_crop_x((video_align_width_ - video_width_) / 2);
	xout_.set_video_crop_y((video_align_height_ - video_height_) / 2);

	// vtc0
	xout_.set_vtc0_reset(1);
	xout_.set_vtc0_mode(1);
	xout_.set_vtc0_active_hsize(video_width_);
	xout_.set_vtc0_active_vsize(video_height_);
	xout_.set_vtc0_frame_hsize(2200);
	xout_.set_vtc0_frame_vsize(1125);
	xout_.set_vtc0_hvalid_start(16);
	xout_.set_vtc0_vvalid_start(4);
	xout_.set_vtc0_hsync_start(8);
	xout_.set_vtc0_hsync_end(2052);
	xout_.set_vtc0_vsync_hstart(0);
	xout_.set_vtc0_vsync_hend(0);
	xout_.set_vtc0_vsync_vstart(3);
	xout_.set_vtc0_vsync_vend(1092);

	xout_.set_sdi_rst_vcnt_num(1);
	xout_.set_sdi_sync_vcnt_num(35);
	xout_.set_sdi_start_vcnt_num(41);
	xout_.set_sdi_end_vcnt_num(1121);
	usleep(2000);
	xout_.set_vtc0_reset(0);

	//vtc1
	xout_.set_vtc1_reset(1);
	xout_.set_vtc1_mode(1);
	xout_.set_vtc1_active_hsize(photo_width_);
	xout_.set_vtc1_active_vsize(photo_height_);
	xout_.set_vtc1_frame_hsize(5620);
	xout_.set_vtc1_frame_vsize(4102);
	xout_.set_vtc1_hvalid_start(250);
	xout_.set_vtc1_vvalid_start(3);
	xout_.set_vtc1_hsync_start(200);
	xout_.set_vtc1_hsync_end(250 + photo_width_ + 50);
	xout_.set_vtc1_vsync_hstart(0);
	xout_.set_vtc1_vsync_hend(0);
	xout_.set_vtc1_vsync_vstart(3);
	xout_.set_vtc1_vsync_vend(3 + photo_height_);

	usleep(2000);
	xout_.set_vtc1_reset(0);


	//等待photo流初始化
	sleep(3);

}

其中的usleep和sleep函数,都是BSP提供的函数,位于sleep.h文件中。

8)GPIO的初始化

int SystemManager::isp_gpio_init(XGpio* instance, u16 dev_id)
{
	int ret;
	ret = XGpio_Initialize(instance, dev_id);
	if (ret != XST_SUCCESS)
		return -1;
	XGpio_SetDataDirection(instance, 1, 0);
	return 0;
}

这里参考了BSP中提供的GPIO的example的例子,封装了gpio_init函数。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
下面补充一个关于reset操作的函数,一并视为初始化相关

9)fpga_reset

void SystemManager::fpga_reset()
{
	xout_.set_ap_reset(1);
	xout_.set_st_reset(1);
	usleep(1000);
	xout_.set_ap_reset(0);
	xout_.set_st_reset(0);
	usleep(1000);

	isp_ap_reset(&isp_gpio_);
}

利用set操作配合以sleep操作,完成内部signal的时序控制。

10)isp_ap_reset

void SystemManager::isp_ap_reset(XGpio* instance)
{
	XGpio_DiscreteWrite(instance, 1, 3);
	usleep(1000);
	XGpio_DiscreteWrite(instance, 1, 0);
	usleep(1000);
}



利用XGpio_DiscreteWrite配合以sleep操作,完成AXI_GPIO的时序控制。

11)isp_ap_set_reset

void SystemManager::isp_ap_set_reset(XGpio* instance, u32 value)
{
	XGpio_DiscreteWrite(instance, 1, value);
	usleep(1000);
}

利用XGpio_DiscreteWrite配合以sleep操作,完成AXI_GPIO的时序控制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值