diff --git a/Example/E01_gpio_demo/libraries/doc/version.txt b/Example/E01_gpio_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E01_gpio_demo/libraries/doc/version.txt +++ b/Example/E01_gpio_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E01_gpio_demo/libraries/zf_common/zf_common_headfile.h b/Example/E01_gpio_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E01_gpio_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E01_gpio_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.a b/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.a and b/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.h b/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_type.h b/Example/E01_gpio_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E01_gpio_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E02_uart_demo/libraries/doc/version.txt b/Example/E02_uart_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E02_uart_demo/libraries/doc/version.txt +++ b/Example/E02_uart_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E02_uart_demo/libraries/zf_common/zf_common_headfile.h b/Example/E02_uart_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E02_uart_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E02_uart_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_config.a b/Example/E02_uart_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E02_uart_demo/libraries/zf_device/zf_device_config.a and b/Example/E02_uart_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_config.h b/Example/E02_uart_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_type.h b/Example/E02_uart_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E02_uart_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E02_uart_demo/user/cpu0_main.c b/Example/E02_uart_demo/user/cpu0_main.c index ae07ee4..d93d56d 100644 --- a/Example/E02_uart_demo/user/cpu0_main.c +++ b/Example/E02_uart_demo/user/cpu0_main.c @@ -80,7 +80,7 @@ uint8 fifo_get_data[64]; uint8 get_data = 0; // 接收数据变量 uint32 fifo_data_count = 0; // fifo 数据个数 -fifo_obj_struct uart_data_fifo; +fifo_struct uart_data_fifo; int core0_main(void) { diff --git a/Example/E03_adc_demo/libraries/doc/version.txt b/Example/E03_adc_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E03_adc_demo/libraries/doc/version.txt +++ b/Example/E03_adc_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E03_adc_demo/libraries/zf_common/zf_common_headfile.h b/Example/E03_adc_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E03_adc_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E03_adc_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_config.a b/Example/E03_adc_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E03_adc_demo/libraries/zf_device/zf_device_config.a and b/Example/E03_adc_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_config.h b/Example/E03_adc_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_type.h b/Example/E03_adc_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E03_adc_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E04_pwm_demo/libraries/doc/version.txt b/Example/E04_pwm_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E04_pwm_demo/libraries/doc/version.txt +++ b/Example/E04_pwm_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E04_pwm_demo/libraries/zf_common/zf_common_headfile.h b/Example/E04_pwm_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E04_pwm_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E04_pwm_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.a b/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.a and b/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.h b/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_type.h b/Example/E04_pwm_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E04_pwm_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E05_pit_demo/libraries/doc/version.txt b/Example/E05_pit_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E05_pit_demo/libraries/doc/version.txt +++ b/Example/E05_pit_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E05_pit_demo/libraries/zf_common/zf_common_headfile.h b/Example/E05_pit_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E05_pit_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E05_pit_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_config.a b/Example/E05_pit_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E05_pit_demo/libraries/zf_device/zf_device_config.a and b/Example/E05_pit_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_config.h b/Example/E05_pit_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_type.h b/Example/E05_pit_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E05_pit_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E06_exit_demo/libraries/doc/version.txt b/Example/E06_exit_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E06_exit_demo/libraries/doc/version.txt +++ b/Example/E06_exit_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E06_exit_demo/libraries/zf_common/zf_common_headfile.h b/Example/E06_exit_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E06_exit_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E06_exit_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_config.a b/Example/E06_exit_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E06_exit_demo/libraries/zf_device/zf_device_config.a and b/Example/E06_exit_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_config.h b/Example/E06_exit_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_type.h b/Example/E06_exit_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E06_exit_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E07_encoder_demo/libraries/doc/version.txt b/Example/E07_encoder_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E07_encoder_demo/libraries/doc/version.txt +++ b/Example/E07_encoder_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E07_encoder_demo/libraries/zf_common/zf_common_headfile.h b/Example/E07_encoder_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E07_encoder_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E07_encoder_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.a b/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.a and b/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.h b/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_type.h b/Example/E07_encoder_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E07_encoder_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E08_eeprom_demo/libraries/doc/version.txt b/Example/E08_eeprom_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E08_eeprom_demo/libraries/doc/version.txt +++ b/Example/E08_eeprom_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_headfile.h b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.a b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.a and b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.h b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_type.h b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E09_timer_demo/libraries/doc/version.txt b/Example/E09_timer_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E09_timer_demo/libraries/doc/version.txt +++ b/Example/E09_timer_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E09_timer_demo/libraries/zf_common/zf_common_headfile.h b/Example/E09_timer_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E09_timer_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E09_timer_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_config.a b/Example/E09_timer_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E09_timer_demo/libraries/zf_device/zf_device_config.a and b/Example/E09_timer_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_config.h b/Example/E09_timer_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_type.h b/Example/E09_timer_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E09_timer_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E10_printf_debug_log_demo/libraries/doc/version.txt b/Example/E10_printf_debug_log_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E10_printf_debug_log_demo/libraries/doc/version.txt +++ b/Example/E10_printf_debug_log_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_headfile.h b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.a b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.a and b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.h b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_type.h b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E11_interrupt_priority_set_demo/libraries/doc/version.txt b/Example/E11_interrupt_priority_set_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/doc/version.txt +++ b/Example/E11_interrupt_priority_set_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_headfile.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.a b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.a and b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_type.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/doc/version.txt b/Example/E12_cpu1_handles_interrupts_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/doc/version.txt +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_headfile.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.a b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.a and b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_type.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E13_dual_core_demo/libraries/doc/version.txt b/Example/E13_dual_core_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E13_dual_core_demo/libraries/doc/version.txt +++ b/Example/E13_dual_core_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_headfile.h b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.a b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.a and b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.h b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_type.h b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/doc/version.txt b/Example/E14_specifies_variable_or_code_location_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/doc/version.txt +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_headfile.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.a b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.a and b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_type.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Example/E15_fft_demo/libraries/doc/version.txt b/Example/E15_fft_demo/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Example/E15_fft_demo/libraries/doc/version.txt +++ b/Example/E15_fft_demo/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Example/E15_fft_demo/libraries/zf_common/zf_common_headfile.h b/Example/E15_fft_demo/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Example/E15_fft_demo/libraries/zf_common/zf_common_headfile.h +++ b/Example/E15_fft_demo/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_config.a b/Example/E15_fft_demo/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Example/E15_fft_demo/libraries/zf_device/zf_device_config.a and b/Example/E15_fft_demo/libraries/zf_device/zf_device_config.a differ diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_config.h b/Example/E15_fft_demo/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_config.h +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.h b/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.h +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_type.h b/Example/E15_fft_demo/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_type.h +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_uart_receiver.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_uart_receiver.h b/Example/E15_fft_demo/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.c b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.c +++ b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.h b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.h +++ b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数==================================================== diff --git a/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt b/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt index bc77a80..54d38d6 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt +++ b/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt @@ -1,3 +1,6 @@ +V3.2.8 + 新增凌瞳无MCU版本驱动 + 新增SBUS遥控器底层驱动 V3.2.7 新增RTK "D" 报头协议 更正陀螺仪宏转换函数 变量增加括号 防止计算错误 diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_headfile.h b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_headfile.h index 86762db..c0d833b 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_headfile.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_headfile.h @@ -100,6 +100,7 @@ #include "zf_device_tft180.h" #include "zf_device_tsl1401.h" #include "zf_device_type.h" +#include "zf_device_uart_receiver.h" #include "zf_device_virtual_oscilloscope.h" #include "zf_device_wifi_uart.h" #include "zf_device_wifi_spi.h" diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.a b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.a index 11bd1cc..ce7da96 100644 Binary files a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.a and b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.a differ diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.h b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.h index 6c8147d..2dffad7 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_config.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增凌瞳静态库函数 ********************************************************************************************************************/ #ifndef _zf_device_config_h_ @@ -43,5 +44,10 @@ unsigned char mt9v03x_set_config_sccb (void *soft_iic_obj, short int b unsigned char mt9v03x_set_exposure_time_sccb (unsigned short int light); unsigned char mt9v03x_set_reg_sccb (unsigned char addr, unsigned short int data); +unsigned char scc8660_set_config_sccb (void *soft_iic_obj, short int buff[10][2]); +unsigned char scc8660_set_brightness_sccb (unsigned short int brightness); +unsigned char scc8660_set_manual_wb_sccb (unsigned short int manual_wb); +unsigned char scc8660_set_reg_sccb (unsigned char reg, unsigned short int data); + #endif diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.c index 38d65ff..ffbe0ee 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.c @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -55,9 +56,12 @@ #include "zf_driver_exti.h" #include "zf_driver_gpio.h" #include "zf_driver_uart.h" +#include "zf_driver_soft_iic.h" #include "zf_device_camera.h" -#include "zf_device_scc8660.h" #include "zf_device_type.h" +#include "zf_device_config.h" + +#include "zf_device_scc8660.h" vuint8 scc8660_finish_flag = 0; // 一场图像采集完成标志位 IFX_ALIGN(4) uint16 scc8660_image[SCC8660_H][SCC8660_W]; @@ -68,6 +72,7 @@ uint8 scc8660_lost_flag = 1; uint8 scc8660_dma_int_num; // 当前DMA中断次数 uint8 scc8660_dma_init_flag; // 是否需要重新初始化 +static scc8660_type_enum scc8660_type; // 需要配置到摄像头的数据 不允许在这修改参数 static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= @@ -77,7 +82,7 @@ static int16 scc8660_set_confing_buffer[SCC8660_CONFIG_FINISH][2]= {SCC8660_AUTO_EXP, SCC8660_AUTO_EXP_DEF}, // 自动曝光 {SCC8660_BRIGHT, SCC8660_BRIGHT_DEF}, // 亮度设置 {SCC8660_FPS, SCC8660_FPS_DEF}, // 图像帧率 - {SCC8660_SET_COL, SCC8660_W}, // 图像列数 + {SCC8660_SET_COL, SCC8660_W * 4}, // 图像列数 {SCC8660_SET_ROW, SCC8660_H}, // 图像行数 {SCC8660_PCLK_DIV, SCC8660_PCLK_DIV_DEF}, // PCLK分频系数 {SCC8660_PCLK_MODE, SCC8660_PCLK_MODE_DEF}, // PCLK模式 @@ -214,71 +219,6 @@ static void scc8660_uart_callback (void) fifo_write_element(&camera_receiver_fifo, data); } -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头场中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_vsync_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_vsync_handler(void) -{ - exti_flag_clear(SCC8660_VSYNC_PIN); - scc8660_dma_int_num = 0; - if(scc8660_dma_init_flag || scc8660_lost_flag) - { - scc8660_dma_init_flag = 0; - IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_link_list_num = dma_init(SCC8660_DMA_CH, - SCC8660_DATA_ADD, - (uint8 *)scc8660_image[0], - SCC8660_PCLK_PIN, - EXTI_TRIGGER_RISING, - SCC8660_IMAGE_SIZE); // 如果超频到300M 倒数第二个参数请设置为FALLING - dma_enable(SCC8660_DMA_CH); - } - else - { - if(1 == scc8660_link_list_num) - { - dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 - } - dma_enable(SCC8660_DMA_CH); - } - scc8660_lost_flag = 1; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 SCC8660摄像头DMA完成中断 -// 参数说明 void -// 返回参数 void -// 使用示例 scc8660_dma_handler(); -//------------------------------------------------------------------------------------------------------------------- -static void scc8660_dma_handler(void) -{ - clear_dma_flag(SCC8660_DMA_CH); - - if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 - { - scc8660_finish_flag = 0; - dma_disable(SCC8660_DMA_CH); - IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); - scc8660_dma_init_flag = 1; - } - else - { - scc8660_dma_int_num++; - if(scc8660_dma_int_num >= scc8660_link_list_num) - { - // 采集完成 - // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) - scc8660_dma_int_num = 0; - scc8660_lost_flag = 0; - scc8660_finish_flag = 1; - dma_disable(SCC8660_DMA_CH); - } - } -} - //------------------------------------------------------------------------------------------------------------------- // 函数简介 获取摄像头 ID // 参数说明 void @@ -390,38 +330,46 @@ uint16 scc8660_get_version (void) // 函数简介 单独设置图像亮度 // 参数说明 data 需要设置的亮度值 // 返回参数 uint8 1-失败 0-成功 -// 使用示例 scc8660_set_bright(data); +// 使用示例 scc8660_set_brightness(data); // 备注信息 调用该函数前请先初始化摄像头配置串口 通过该函数设置的参数,不会被51单片机保存 //------------------------------------------------------------------------------------------------------------------- -uint8 scc8660_set_bright (uint16 data) +uint8 scc8660_set_brightness (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_BRIGHT; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_BRIGHT; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_brightness_sccb(data); } return return_state; } @@ -436,32 +384,40 @@ uint8 scc8660_set_bright (uint16 data) uint8 scc8660_set_white_balance (uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_MANUAL_WB; - uart_buffer[2] = data >> 8; - uart_buffer[3] = (uint8)data; - - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_MANUAL_WB; + uart_buffer[2] = data >> 8; + uart_buffer[3] = (uint8)data; + + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + } + else { - return_state = 1; + return_state = scc8660_set_manual_wb_sccb(data); } return return_state; } @@ -477,43 +433,117 @@ uint8 scc8660_set_white_balance (uint16 data) uint8 scc8660_set_reg (uint8 addr, uint16 data) { uint8 return_state = 0; - uint8 uart_buffer[4]; - uint16 temp; - uint16 timeout_count = 0; - uint32 uart_buffer_index = 0; - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_ADDR; - uart_buffer[2] = 0x00; - uart_buffer[3] = (uint8)addr; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - system_delay_ms(10); - uart_buffer[0] = 0xA5; - uart_buffer[1] = SCC8660_SET_REG_DATA; - temp = data; - uart_buffer[2] = temp >> 8; - uart_buffer[3] = (uint8)temp; - uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); - - do + if(SCC8660_UART == scc8660_type) { - if(3 <= fifo_used(&camera_receiver_fifo)) + uint8 uart_buffer[4]; + uint16 temp; + uint16 timeout_count = 0; + uint32 uart_buffer_index = 0; + + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_ADDR; + uart_buffer[2] = 0x00; + uart_buffer[3] = (uint8)addr; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + system_delay_ms(10); + uart_buffer[0] = 0xA5; + uart_buffer[1] = SCC8660_SET_REG_DATA; + temp = data; + uart_buffer[2] = temp >> 8; + uart_buffer[3] = (uint8)temp; + uart_write_buffer(SCC8660_COF_UART, uart_buffer, 4); + + do { - uart_buffer_index = 3; - fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); - temp = uart_buffer[1] << 8 | uart_buffer[2]; - break; + if(3 <= fifo_used(&camera_receiver_fifo)) + { + uart_buffer_index = 3; + fifo_read_buffer(&camera_receiver_fifo, uart_buffer, &uart_buffer_index, FIFO_READ_AND_CLEAN); + temp = uart_buffer[1] << 8 | uart_buffer[2]; + break; + } + system_delay_ms(1); + }while(SCC8660_INIT_TIMEOUT > timeout_count ++); + if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + { + return_state = 1; } - system_delay_ms(1); - }while(SCC8660_INIT_TIMEOUT > timeout_count ++); - if((temp != data) || (SCC8660_INIT_TIMEOUT <= timeout_count)) + + } + else { - return_state = 1; + return_state = scc8660_set_reg_sccb(addr, data); } return return_state; } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头场中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_vsync_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_vsync_handler(void) +{ + exti_flag_clear(SCC8660_VSYNC_PIN); + scc8660_dma_int_num = 0; + if(scc8660_dma_init_flag || scc8660_lost_flag) + { + scc8660_dma_init_flag = 0; + IfxDma_resetChannel(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_link_list_num = dma_init(SCC8660_DMA_CH, + SCC8660_DATA_ADD, + (uint8 *)scc8660_image[0], + SCC8660_PCLK_PIN, + EXTI_TRIGGER_RISING, + SCC8660_IMAGE_SIZE); + dma_enable(SCC8660_DMA_CH); + } + else + { + if(1 == scc8660_link_list_num) + { + dma_set_destination(SCC8660_DMA_CH, (uint8 *)scc8660_image[0]); // 没有采用链接传输模式 重新设置目的地址 + } + dma_enable(SCC8660_DMA_CH); + } + scc8660_lost_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SCC8660摄像头DMA完成中断 +// 参数说明 void +// 返回参数 void +// 使用示例 scc8660_dma_handler(); +//------------------------------------------------------------------------------------------------------------------- +static void scc8660_dma_handler(void) +{ + clear_dma_flag(SCC8660_DMA_CH); + + if(IfxDma_getChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH)) // 图像错位判断 + { + scc8660_finish_flag = 0; + dma_disable(SCC8660_DMA_CH); + IfxDma_clearChannelTransactionRequestLost(&MODULE_DMA, SCC8660_DMA_CH); + scc8660_dma_init_flag = 1; + } + else + { + scc8660_dma_int_num++; + if(scc8660_dma_int_num >= scc8660_link_list_num) + { + // 采集完成 + // 一副图像从采集开始到采集结束耗时3.8MS左右(50FPS、188*120分辨率) + scc8660_dma_int_num = 0; + scc8660_lost_flag = 0; + scc8660_finish_flag = 1; + dma_disable(SCC8660_DMA_CH); + } + } +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 SCC8660 摄像头初始化 // 参数说明 void @@ -524,51 +554,54 @@ uint8 scc8660_set_reg (uint8 addr, uint16 data) uint8 scc8660_init (void) { uint8 return_state = 0; - uint16 scc8660_version = 0; + soft_iic_info_struct scc8660_iic_struct; + // 初始化之前拉高场与像素引脚 gpio_init(P02_0, GPO, GPIO_HIGH, GPO_PUSH_PULL); gpio_init(P02_1, GPO, GPIO_HIGH, GPO_PUSH_PULL); - // 初始换串口 配置摄像头 - uart_init(SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); - uart_rx_interrupt(SCC8660_COF_UART, 1); - - system_delay_ms(200); - - set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, scc8660_uart_callback); // 设置连接摄像头类型 - camera_fifo_init(); do { - // 等待摄像头上电初始化成功 方式有两种:延时或者通过获取配置的方式 二选一 - // system_delay_ms(1000); // 延时方式 - scc8660_version = scc8660_get_version(); // 获取配置的方式 - if(scc8660_set_config(scc8660_set_confing_buffer)) + system_delay_ms(200); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, NULL); // 设置连接摄像头类型 + // 首先尝试SCCB通讯 + scc8660_type = SCC8660_SCCB; + soft_iic_init(&scc8660_iic_struct, 0, SCC8660_COF_IIC_DELAY, SCC8660_COF_IIC_SCL, SCC8660_COF_IIC_SDA); + if(scc8660_set_config_sccb(&scc8660_iic_struct, scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; - // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 - // 检查一下接线有没有问题 如果没问题可能就是坏了 - zf_log(0, "SCC8660 set config error."); - break; - } + // SCCB通讯失败,尝试串口通讯 + scc8660_type = SCC8660_UART; + camera_fifo_init(); + set_camera_type(CAMERA_COLOR, scc8660_vsync_handler, scc8660_dma_handler, &scc8660_uart_callback); // 设置连接摄像头类型 + uart_init (SCC8660_COF_UART, SCC8660_COF_BAUR, SCC8660_COF_UART_RX, SCC8660_COF_UART_TX); //初始换串口 配置摄像头 + uart_rx_interrupt(SCC8660_COF_UART, 1); + fifo_clear(&camera_receiver_fifo); - if(0 == return_state) - { - // 获取配置便于查看配置是否正确 - if(scc8660_get_config(scc8660_get_confing_buffer)) + if(scc8660_set_config(scc8660_set_confing_buffer)) { - set_camera_type(NO_CAMERE, NULL, NULL, NULL); - return_state = 1; // 如果程序在输出了断言信息 并且提示出错位置在这里 - // 那么就是串口通信出错并超时退出了 + // 那么就是通信出错并超时退出了 // 检查一下接线有没有问题 如果没问题可能就是坏了 zf_log(0, "SCC8660 set config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; break; } - scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); + // 获取配置便于查看配置是否正确 + if(scc8660_get_config(scc8660_get_confing_buffer)) + { + // 如果程序在输出了断言信息 并且提示出错位置在这里 + // 那么就是串口通信出错并超时退出了 + // 检查一下接线有没有问题 如果没问题可能就是坏了 + zf_log(0, "SCC8660 get config error."); + set_camera_type(NO_CAMERE, NULL, NULL, NULL); + return_state = 1; + break; + } } + + scc8660_link_list_num = camera_init(SCC8660_DATA_ADD, (uint8 *)scc8660_image[0], SCC8660_IMAGE_SIZE); }while(0); return return_state; diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.h b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.h index 537283a..6790330 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_scc8660.h @@ -31,7 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version -* 2023-04-28 pudding 增加中文注释说明 +* 2024-02-02 pudding 新增无MCU凌瞳驱动 ********************************************************************************************************************/ /********************************************************************************************************************* * 接线定义: @@ -59,35 +59,36 @@ #define SCC8660_COF_UART_TX (UART1_RX_P02_3) // 凌瞳 UART-TX 引脚 要接在单片机 RX 上 #define SCC8660_COF_UART_RX (UART1_TX_P02_2) // 凌瞳 UART-RX 引脚 要接在单片机 TX 上 +#define SCC8660_COF_IIC_DELAY (800) // 凌瞳 IIC 延时 +#define SCC8660_COF_IIC_SCL (P02_3) // 凌瞳 IIC-SCL 引脚 +#define SCC8660_COF_IIC_SDA (P02_2) // 凌瞳 IIC-SDA 引脚 + #define SCC8660_DMA_CH (IfxDma_ChannelId_5) - #define SCC8660_PCLK_PIN (ERU_CH2_REQ14_P02_1) // PCLK 触发信号 TIM_ETR 引脚禁止随意修改 - #define SCC8660_VSYNC_PIN (ERU_CH3_REQ6_P02_0 ) // 场中断引脚 - #define SCC8660_DATA_PIN (P00_0) // 数据引脚 这里是 只能是 GPIOx0 或者 GPIOx8 开始 连续八个引脚例如 F0-F7 #define SCC8660_DATA_ADD (get_port_in_addr(SCC8660_DATA_PIN)) #define SCC8660_INIT_TIMEOUT (0x00F0) // 默认的摄像头初始化超时时间 毫秒为单位 //================================================定义 SCC8660 基本配置================================================ -//================================================定义 SCC8660 参数配置================================================ -#define SCC8660_W (160) // 实际图像分辨率宽度 可选参数为:160 180 -#define SCC8660_H (120) // 实际图像分辨率高度 可选参数为:120 160 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== +#define SCC8660_W (160) // 图像宽度 可选参数为:160 80 40 +#define SCC8660_H (120) // 图像高度 可选参数为:120 160 240 #define SCC8660_IMAGE_SIZE (SCC8660_W * 2 * SCC8660_H) // 整体图像大小 SCC8660_W*2*SCC8660_H 不能超过 65535 #define SCC8660_AUTO_EXP_DEF (0 ) // 自动曝光 默认不开启自动曝光设置 范围 [0-1] 0为关闭 -#define SCC8660_BRIGHT_DEF (300) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 +#define SCC8660_BRIGHT_DEF (500) // 亮度设置 手动曝光默认:300 手动曝光时:参数范围0-65535 自动曝光推荐值:100 自动曝光时参数设置范围0-255 #define SCC8660_FPS_DEF (50 ) // 图像帧率 默认:50 可选参数为:60 50 30 25。 实际帧率还需要看SCC8660_PCLK_DIV参数的设置 -#define SCC8660_PCLK_DIV_DEF (5 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> +#define SCC8660_PCLK_DIV_DEF (2 ) // PCLK分频系数 默认:5 可选参数为:<0:1/1> <1:2/3> <2:1/2> <3:1/3> <4:1/4> <5:1/8> // 分频系数越大,PCLK频率越低,降低PCLK可以减轻DVP接口的干扰,但降低PCLK频率则会影响帧率。若无特殊需求请保持默认。 // 例如设置FPS为50帧,但是pclk分频系数选择的为5,则摄像头输出的帧率为50*(1/8)=6.25帧 // 其他参数不变的情况下,SCC8660_PCLK_DIV参数越大图像会越亮 -#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> -#define SCC8660_COLOR_MODE_DEF (1 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) -#define SCC8660_DATA_FORMAT_DEF (1 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) -#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 -//================================================定义 SCC8660 参数配置================================================ +#define SCC8660_PCLK_MODE_DEF (0 ) // PCLK模式 默认:0 可选参数为:[0,1] 0:不输出消隐信号 1:输出消隐信号 <通常都设置为0,如果使用STM32的DCMI接口采集需要设置为1> +#define SCC8660_COLOR_MODE_DEF (0 ) // 图像色彩模式 默认:0 可选参数为:[0,1] 0:正常彩色模式 1:鲜艳模式(色彩饱和度提高) +#define SCC8660_DATA_FORMAT_DEF (0 ) // 输出数据格式 默认:0 可选参数为:[0-3] 0:RGB565 1:RGB565(字节交换) 2:YUV422(YUYV) 3:YUV422(UYVY) +#define SCC8660_MANUAL_WB_DEF (0 ) // 手动白平衡 默认:0 可选参数为:[0,0x65-0xa0] 0:关闭手动白平衡,启用自动白平衡 其他:手动白平衡 手动白平衡时 参数范围0x65-0xa0 +//================================================定义 SCC8660 参数配置(仅支持凌瞳高帧率版本)=========================== //===============================================定义 SCC8660 参数结构体================================================ typedef enum @@ -116,6 +117,14 @@ typedef enum }scc8660_cmd_enum; //===============================================定义 SCC8660 参数结构体================================================ +//===============================================摄像头类型枚举体======================================================= +typedef enum +{ + SCC8660_UART, + SCC8660_SCCB, +}scc8660_type_enum; +//===============================================摄像头类型枚举体======================================================= + //===============================================声明 SCC8660 全局变量================================================= extern vuint8 scc8660_finish_flag; // 一场图像采集完成标志位 extern uint16 scc8660_image[SCC8660_H][SCC8660_W]; // 图像保存数组 diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_type.h b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_type.h index 3b124fe..6c2b8da 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_type.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_type.h @@ -56,6 +56,7 @@ typedef enum WIRELESS_UART, // 无线串口 BLUETOOTH_CH9141, // 蓝牙 CH9141 WIFI_UART, // 串口 WiFi + RECEIVER_UART, // 枪式遥控器 }wireless_type_enum; typedef enum diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_uart_receiver.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_uart_receiver.c new file mode 100644 index 0000000..3ebb3bd --- /dev/null +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_uart_receiver.c @@ -0,0 +1,134 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ + +#include "zf_device_type.h" +#include "zf_driver_uart.h" +#include "zf_driver_timer.h" +#include "zf_device_uart_receiver.h" + +uart_receiver_struct uart_receiver ; // 串口接收机通道数据与状态 + +uint8 uart_receiver_data[REV_DATA_LEN] = {0}; // 接收器原始数据 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 获取两次调用uart_receiver_interval_time函数时间间隔 +// 参数说明 void +// 返回参数 uint32 返回从开始到现在的时间(单位1us) +// 使用示例 uint32 time = uart_receiver_interval_time(); +// 备注信息 内部调用 +//------------------------------------------------------------------------------------------------------------------- +static uint32 uart_receiver_interval_time (void) +{ + static uint32 time_last = 0; + uint32 time, interval_time; + uint32 stm_clk; + + stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + + time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)(IfxCpu_getCoreId()))); + interval_time = time - time_last; + time_last = time; + interval_time = (uint32)((uint64)interval_time * 1000000 / stm_clk); + + return interval_time; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 SBUS数据解析 +// 参数说明 *remote_data 接收遥控器数据的地址 +// 参数说明 *bufer 原始数据 +// 返回参数 void +// 使用示例 +// 备注信息 对sbus数据解析进行解析 +//------------------------------------------------------------------------------------------------------------------- +static void uart_receiver_analysis (uart_receiver_struct *remote_data,uint8 * buffer) +{ + uint8 num = 0; + remote_data->channel[num++] = (buffer[1] |buffer[ 2] << 8 ) & 0x07FF; + remote_data->channel[num++] = (buffer[2] >> 3 | buffer[3] << 5 ) & 0x07FF; + remote_data->channel[num++] = (buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10 ) & 0x07FF; + remote_data->channel[num++] = (buffer[5] >> 1 | buffer[6] << 7 ) & 0x07FF; + remote_data->channel[num++] = (buffer[6] >> 4 | buffer[7] << 4 ) & 0x07FF; + remote_data->channel[num++] = (buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9 ) & 0x07FF; + remote_data->state = (SBUS_NORMAL_STATE == buffer[23]) ? 1 : 0; + uart_receiver.finsh_flag = 1; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机模块 串口中断回调函数 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_callback(); +// 备注信息 该函数在 ISR 文件 串口中断程序通过uart_receiver_uart_handler函数指针被调用 +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_callback(void) +{ + static vuint8 length = 0; + + if (uart_receiver_interval_time() > 3000) + { + length = 0; + } + uart_receiver_data[length++] = uart_read_byte(UART_RECEVIER_UART_INDEX); + if ( (REV_DATA_LEN == length) // 如果帧长、帧头、帧尾满足协议 + && (FRAME_STAR == uart_receiver_data[0]) + && (FRAME_END == uart_receiver_data[24])) + { + uart_receiver_analysis(&uart_receiver, uart_receiver_data); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 串口接收机初始化 +// 参数说明 void +// 返回参数 void +// 使用示例 uart_receiver_init(); +//------------------------------------------------------------------------------------------------------------------- +void uart_receiver_init(void) +{ + uart_sbus_init(UART_RECEVIER_UART_INDEX, SBUS_UART_BAUDRATE, UART_RECEVIER_TX_PIN, UART_RECEVIER_RX_PIN); + + // 设置串口中断回调函数 + set_wireless_type(RECEIVER_UART, uart_receiver_callback); +} diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_uart_receiver.h b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_uart_receiver.h new file mode 100644 index 0000000..948ab2f --- /dev/null +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_uart_receiver.h @@ -0,0 +1,72 @@ +/********************************************************************************************************************* +* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 +* Copyright (c) 2022 SEEKFREE 逐飞科技 +* +* 本文件是 TC264 开源库的一部分 +* +* TC264 开源库 是免费软件 +* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款 +* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它 +* +* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证 +* 甚至没有隐含的适销性或适合特定用途的保证 +* 更多细节请参见 GPL +* +* 您应该在收到本开源库的同时收到一份 GPL 的副本 +* 如果没有,请参阅 +* +* 额外注明: +* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本 +* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中 +* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 zf_device_uart_receiver +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.20 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2022-11-04 JKS first version +********************************************************************************************************************/ +/********************************************************************************************************************* +* 接线定义: +* ------------------------------------ +* 模块管脚 单片机管脚 +* TXD 查看 zf_device_uart_receiver.h 中 UART_RECEVIER_RX_PIN 宏定义 +* GND 电源地 +* 5V 5V电源 +* ------------------------------------ +********************************************************************************************************************/ +#ifndef _zf_device_uart_receiver_h +#define _zf_device_uart_receiver_h + +#include "zf_common_typedef.h" + +#define UART_RECEVIER_UART_INDEX UART_2 // 定义串口接收机使用的串口 +#define UART_RECEVIER_TX_PIN UART2_TX_P10_5 // 遥控器接收机没有这个引脚,仅用于串口初始化时占位使用 +#define UART_RECEVIER_RX_PIN UART2_RX_P10_6 // 串口接收机的TX引脚 连接单片机的RX引脚 +#define SBUS_UART_BAUDRATE (100000) // 指定 SBUS 串口所使用的的串口波特率 (用户不可修改) +#define UART_RECEVIER_CHANNEL_NUM ( 6 ) // 定义遥控器通道数量 (用户不可修改) + +#define REV_DATA_LEN ( 25 ) // SBUS帧长 +#define FRAME_STAR ( 0X0F ) // 帧头信息 +#define FRAME_END ( 0X00 ) // 帧尾信息 +#define SBUS_NORMAL_STATE ( 0X03 ) // 正常状态 +#define SBUS_ABNORMAL_STATE ( 0X0F ) // 失控状态 + +typedef struct +{ + uint16 channel[UART_RECEVIER_CHANNEL_NUM]; // CH1-CH6通道数据 + uint8 state; // 遥控器状态(1表示正常,否则表示失控) + uint8 finsh_flag; // 1:表示成功接收到一帧遥控器数据 +}uart_receiver_struct; + +extern uart_receiver_struct uart_receiver; // 串口接收机通道数据与状态 + +void uart_receiver_init(void); + +#endif diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.c b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.c index fb89b55..b2fa521 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.c @@ -404,6 +404,55 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) } } +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 sbus初始化 +// 参数说明 uartn 串口通道(UART_0,UART_1,UART_2,UART_3) +// 参数说明 baud 串口波特率 +// 参数说明 tx_pin 串口发送引脚号 +// 参数说明 rx_pin 串口接收引脚号 +// 返回参数 void +// 使用示例 uart_sbus_init(UART_2, 100000, UART2_TX_P10_5, UART2_RX_P10_6); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin) +{ + + boolean interrupt_state = disableInterrupts(); + + volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn); + + IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); // 初始化化配置结构体 + + uart_set_buffer(uartn); // 设置缓冲区 + + uart_set_interrupt_priority(uartn); // 设置中断优先级 + + uart_config.clockSource = IfxAsclin_ClockSource_ascFastClock; // 使用高速时钟 最大波特率6.25M + uart_config.baudrate.prescaler = 4; + uart_config.baudrate.baudrate = (float32)baud; + uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8; + + uart_config.frame.stopBit = IfxAsclin_StopBit_2; //停止位 + uart_config.frame.parityType = IfxAsclin_ParityType_even; //偶校验 + uart_config.frame.dataLength = IfxAsclin_DataLength_8; + uart_config.frame.parityBit = TRUE; //启动校验 + + IfxAsclin_Asc_Pins pins; // 设置引脚 + pins.cts = NULL; + pins.rts = NULL; + uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx); + pins.rxMode = IfxPort_InputMode_pullUp; + pins.txMode = IfxPort_OutputMode_pushPull; + pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; + uart_config.pins = &pins; + + IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config); + uart_rx_interrupt(uartn, 1); + uart_tx_interrupt(uartn, 0); + restoreInterrupts(interrupt_state); + +} + //------------------------------------------------------------------------------------------------------------------- // 函数简介 串口初始化 // 参数说明 uartn 串口模块号(UART_0,UART_1,UART_2,UART_3) diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.h b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.h index cdc55ab..abdc10a 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_uart.h @@ -125,6 +125,7 @@ uint8 uart_query_byte (uart_index_enum uartn, uint8 *dat); void uart_tx_interrupt (uart_index_enum uartn, uint32 status); void uart_rx_interrupt (uart_index_enum uartn, uint32 status); +void uart_sbus_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); void uart_init (uart_index_enum uartn, uint32 baud, uart_tx_pin_enum tx_pin, uart_rx_pin_enum rx_pin); //====================================================串口 基础函数====================================================