当前位置: 首页 > news >正文

AI-Talk开发板之Camera

一、说明

 AI-Talk开发板配备了一只DVP摄像头,型号GC0328,像素30万。

1、接口

2、与处理器的信号连接

使用i2c1接口。 

 二、工程

1、测试代码

使用duomotai_ap sdk中的例程进行测试。

2、设备树

设备树文件路径:duomotai_ap/.sdk/csk/boards/arm/csk6011a_box_lite/csk6011a_box_lite.dts

在i2c1节点下添加gc0328的配置

gc0328: gc0328@21 {compatible = "galaxyc,gc0328";status = "okay";reg = <0x21>;reset-gpios = <&exgpioa 1 1>;pwdn-gpios = <&exgpioc 7 0>;
};
3、驱动

驱动文件路径:duomotai_ap/.sdk/csk/drivers/video/gc0328.c。

内核加载驱动后,首先执行gc0328_init()函数,启动函数会设置pwdn_gpios和reset_gpios的状态,代码如下:

static int gc0328_init(const struct device *dev)
{LOG_INF("Galaxyc GC0328 init");struct gc0328_data *drv_data = dev->data;int ret = 0;if (drv_data->pwdn_gpios.port) {gpio_pin_configure_dt(&drv_data->pwdn_gpios, GPIO_OUTPUT_ACTIVE);gpio_pin_set_dt(&drv_data->pwdn_gpios, 0);}if (drv_data->reset_gpios.port) {gpio_pin_configure_dt(&drv_data->reset_gpios, GPIO_OUTPUT_ACTIVE);gpio_pin_set_dt(&drv_data->reset_gpios, 0);k_sleep(K_MSEC(3));gpio_pin_set_dt(&drv_data->reset_gpios, 1);k_sleep(K_MSEC(1));}// ret = gc0328_reg_init(dev);return ret;
}

如果pwdn_gpios和reset_gpios使用的是exmcu的管脚,那可能不会成功,根据启动日志可以看出,内核会先加载gc0328的驱动,再加载exmcu的驱动,那么加载gc0328的驱动时,exmcu还无法操作。

由于内核加载gc0328的驱动时,csk6011a还未输出mclk,所以没有在gc0328_init()中执行gc0328_reg_init(dev)函数,而是应用启动之后调用gc0328_set_ctrl()函数初始化sensor。

static int gc0328_set_ctrl(const struct device *dev, unsigned int cid, void *value)
{LOG_DBG("gc0328 set ctrl %d", cid);int ret = 0;switch (cid) {case VIDEO_CID_HFLIP:ret = gc0328_set_horizontal_mirror(dev, *(int *)value);break;case VIDEO_CID_VFLIP:ret = gc0328_set_vertical_flip(dev, *(int *)value);break;/*该sensor只有在mclk有输入时钟的情况下,i2c才能正常通信,所以并不能在内核设备初始化流程中进行sensor初始化。目前是通过set_ctrl来提供sensor初始化的api.*/case VIDEO_CID_INIT:k_sleep(K_MSEC(10));ret = gc0328_reg_init(dev);break;default:return -ENOTSUP;}return ret;
}

三、调试

1、启动日志
[00:00:00.000,000] [<inf> gc0328: Galaxyc GC0328 init[00:00:00.050,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.100,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.150,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.200,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.251,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.301,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.351,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.401,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.454,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.504,000] [1;31m<err> i2c_csk: Wait I2C complete time out.[0m
[00:00:00.505,000] [0m<inf> csk6_spi: SPI REG ADDR:0x45500000[0m
[00:00:00.506,000] [0m<inf> csk6_spi: SPI REG ADDR:0x45400000[0m
[00:00:00.506,000] [0m<inf> csk6_exmcu_i2c: exmcu addr:0x6C[0m
[00:00:00.546,000] [0m<inf> csk6_exmcu_i2c: exmcu info, chip type:ch32v003, ver:1.3
[00:00:00.546,000] [0m<inf> pwm_csk_ch32v003: pwm csk ch32v003 init, freq:48000000, pres:480
[00:00:00.546,000] [0m<inf> display_st7789v: st7789v_init
[00:00:00.567,000] [0m<dbg> display_st7789v: st7789v_reset_display: Resetting display[0m[00:00:00.726,000] [0m<inf> display_st7789v: st7789v_init done
m<inf> csk6_dvp: sensor dev gc0328@21
[00:00:00.736,000] [0m<inf> gc0328: Galaxyc GC0328 init successful, pid 0x9D
2、分析日志

内核启动后会先初始化gc0328,但不成功,有两种原因。

一是此时由于csk6011a还未产生mclk,导致gc0328没有启动,所以i2c通信失败。

二是由于reset和pwdn是接在exmcu上的,此时还没加载exmcu的驱动,无法将reset和pwdn设置到正确的状态,gc0328可能处于复位或关机状态。

四、修改驱动

1、修改gc0328_init()函数

如果pwdn_gpios和reset_gpios使用的是exmcu的引脚,这里设置状态也无效,所以屏蔽函数里面所有的代码:

static int gc0328_init(const struct device *dev)
{LOG_INF("Galaxyc GC0328 init null");
/* struct gc0328_data *drv_data = dev->data;int ret = 0;if (drv_data->pwdn_gpios.port) {gpio_pin_configure_dt(&drv_data->pwdn_gpios, GPIO_OUTPUT_ACTIVE);gpio_pin_set_dt(&drv_data->pwdn_gpios, 0);}if (drv_data->reset_gpios.port) {gpio_pin_configure_dt(&drv_data->reset_gpios, GPIO_OUTPUT_ACTIVE);gpio_pin_set_dt(&drv_data->reset_gpios, 0);k_sleep(K_MSEC(3));gpio_pin_set_dt(&drv_data->reset_gpios, 1);k_sleep(K_MSEC(1));}
*/// ret = gc0328_reg_init(dev);//return ret;return 0;
}
2、修改gc0328_set_ctrl()函数

在代码“case VIDEO_CID_INIT:”之后设置pwdn_gpios和reset_gpios状态的代码,修改之后代码如下:

	case VIDEO_CID_INIT:struct gc0328_data *drv_data = dev->data;if (drv_data->pwdn_gpios.port) {gpio_pin_configure_dt(&drv_data->pwdn_gpios, GPIO_OUTPUT_ACTIVE);gpio_pin_set_dt(&drv_data->pwdn_gpios, 0);}if (drv_data->reset_gpios.port) {gpio_pin_configure_dt(&drv_data->reset_gpios, GPIO_OUTPUT_ACTIVE);gpio_pin_set_dt(&drv_data->reset_gpios, 0);k_sleep(K_MSEC(3));gpio_pin_set_dt(&drv_data->reset_gpios, 1);k_sleep(K_MSEC(1));}k_sleep(K_MSEC(10));ret = gc0328_reg_init(dev);break;

如果pwdn_gpios和reset_gpios使用的是exmcu的引脚,这样才能将pwdn_gpios和reset_gpios设置到正确的状态。


http://www.mrgr.cn/news/78039.html

相关文章:

  • # linux 清理指定目录下,指定时间的历史文件
  • fastapi入门
  • 【STM32】MPU6050初始化常用寄存器说明及示例代码
  • python中如何使用指数
  • 信息安全设计第11周预习报告
  • 如何使用AWS Lambda构建一个云端工具(超详细)
  • OpenCV基础(3)
  • 优化Docker镜像:提升部署效率与降低资源消耗
  • Spring Boot 与 Java 决策树:构建智能分类系统
  • 数字逻辑(一)——导论
  • 241125学习日志——[CSDIY] [ByteDance] 后端训练营 [18]
  • 车载摄像camera基础知识和评估
  • 2024年底-Arch linux或转为0BSD许可证!
  • 打造智能扩容新纪元:Kubernetes Custom Metrics深度解析
  • Vue 修饰符的作用与应用,应用场景详细介绍
  • 栈、队列、链表
  • 241124学习日志——[CSDIY] [ByteDance] 后端训练营 [14]
  • 传输控制协议(TCP)和用户数据报协议(UDP)
  • WebSocket 常见问题及解决方案
  • MySQL的UPDATE(更新数据)详解
  • Sickos1.1 详细靶机思路 实操笔记
  • 10、PyTorch autograd使用教程
  • 生成对抗网络模拟缺失数据,辅助PAMAP2数据集仿真实验
  • 手机发展史介绍
  • 韩顺平 一周学会Linux | Linux 实操篇-实用指令
  • 卡达掐发展史