diff --git a/Example/E01_gpio_demo/.cproject b/Example/E01_gpio_demo/.cproject index 41ea8bc..3c498e2 100644 --- a/Example/E01_gpio_demo/.cproject +++ b/Example/E01_gpio_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E01_gpio_demo/libraries/doc/version.txt b/Example/E01_gpio_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E01_gpio_demo/libraries/doc/version.txt +++ b/Example/E01_gpio_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E01_gpio_demo/libraries/zf_common/zf_common_debug.c b/Example/E01_gpio_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E01_gpio_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E01_gpio_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.c b/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.h b/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E01_gpio_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E01_gpio_demo/libraries/zf_common/zf_common_typedef.h b/Example/E01_gpio_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E01_gpio_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E01_gpio_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant.c b/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_detector.h b/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant.h similarity index 55% rename from Example/E03_adc_demo/libraries/zf_device/zf_device_detector.h rename to Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant.h index ee2ea7e..d02abb1 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_detector.h +++ b/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant.h @@ -1,4 +1,4 @@ -/********************************************************************************************************************* +/*/********************************************************************************************************************* * TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 * Copyright (c) 2022 SEEKFREE 逐飞科技 * @@ -21,7 +21,7 @@ * 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 * 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) * -* 文件名称 zf_device_detector +* 文件名称 seekfree_assistant * 公司名称 成都逐飞科技有限公司 * 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 * 开发环境 ADS v1.9.4 @@ -30,67 +30,54 @@ * * 修改记录 * 日期 作者 备注 -* 2023-05-27 pudding first version +* 2023-11-29 pudding first version ********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ #include "zf_common_typedef.h" #include "zf_common_debug.h" // 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) // 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) // 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) // 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) // 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) // 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) // 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) // 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) // 摄像头类型枚举 typedef enum { // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; // 摄像头类型枚举 typedef enum @@ -100,7 +87,7 @@ typedef enum Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; +}seekfree_assistant_boundary_type_enum; typedef struct { @@ -108,8 +95,8 @@ typedef struct uint8 channel_num; // 高四位为功能字 低四位为通道数量 uint8 check_sum; // 和校验 uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; typedef struct @@ -120,7 +107,7 @@ typedef struct uint8 length; // 包长度(仅包含协议部分) uint16 image_width; // 图像宽度 uint16 image_height; // 图像高度 -}detector_camera_struct; +}seekfree_assistant_camera_struct; typedef struct @@ -130,19 +117,19 @@ typedef struct uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 uint8 length; // 包长度(仅包含协议部分) uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 + uint8 valid_flag; // 通道标识 uint8 reserve; // 保留 -}detector_camera_dot_struct; +}seekfree_assistant_camera_dot_struct; typedef struct { void *image_addr; // 摄像头地址 uint16 width; // 图像宽度 uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; typedef struct { @@ -151,23 +138,24 @@ typedef struct uint8 channel; // 通道 uint8 check_sum; // 和校验 float data; // 数据 -}detector_parameter_struct; +}seekfree_assistant_parameter_struct; -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); #endif - diff --git a/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E01_gpio_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.h b/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_detector.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E01_gpio_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E01_gpio_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E01_gpio_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E02_uart_demo/.cproject b/Example/E02_uart_demo/.cproject index 270c25d..37f1cd3 100644 --- a/Example/E02_uart_demo/.cproject +++ b/Example/E02_uart_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E02_uart_demo/libraries/doc/version.txt b/Example/E02_uart_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E02_uart_demo/libraries/doc/version.txt +++ b/Example/E02_uart_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E02_uart_demo/libraries/zf_common/zf_common_debug.c b/Example/E02_uart_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E02_uart_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E02_uart_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.c b/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.h b/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E02_uart_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E02_uart_demo/libraries/zf_common/zf_common_typedef.h b/Example/E02_uart_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E02_uart_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E02_uart_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant.c b/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E01_gpio_demo/libraries/zf_device/zf_device_detector.h b/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant.h similarity index 55% rename from Example/E01_gpio_demo/libraries/zf_device/zf_device_detector.h rename to Example/E02_uart_demo/libraries/zf_components/seekfree_assistant.h index ee2ea7e..d02abb1 100644 --- a/Example/E01_gpio_demo/libraries/zf_device/zf_device_detector.h +++ b/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant.h @@ -1,4 +1,4 @@ -/********************************************************************************************************************* +/*/********************************************************************************************************************* * TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 * Copyright (c) 2022 SEEKFREE 逐飞科技 * @@ -21,7 +21,7 @@ * 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 * 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) * -* 文件名称 zf_device_detector +* 文件名称 seekfree_assistant * 公司名称 成都逐飞科技有限公司 * 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 * 开发环境 ADS v1.9.4 @@ -30,67 +30,54 @@ * * 修改记录 * 日期 作者 备注 -* 2023-05-27 pudding first version +* 2023-11-29 pudding first version ********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ #include "zf_common_typedef.h" #include "zf_common_debug.h" // 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) // 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) // 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) // 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) // 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) // 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) // 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) // 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) // 摄像头类型枚举 typedef enum { // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; // 摄像头类型枚举 typedef enum @@ -100,7 +87,7 @@ typedef enum Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; +}seekfree_assistant_boundary_type_enum; typedef struct { @@ -108,8 +95,8 @@ typedef struct uint8 channel_num; // 高四位为功能字 低四位为通道数量 uint8 check_sum; // 和校验 uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; typedef struct @@ -120,7 +107,7 @@ typedef struct uint8 length; // 包长度(仅包含协议部分) uint16 image_width; // 图像宽度 uint16 image_height; // 图像高度 -}detector_camera_struct; +}seekfree_assistant_camera_struct; typedef struct @@ -130,19 +117,19 @@ typedef struct uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 uint8 length; // 包长度(仅包含协议部分) uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 + uint8 valid_flag; // 通道标识 uint8 reserve; // 保留 -}detector_camera_dot_struct; +}seekfree_assistant_camera_dot_struct; typedef struct { void *image_addr; // 摄像头地址 uint16 width; // 图像宽度 uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; typedef struct { @@ -151,23 +138,24 @@ typedef struct uint8 channel; // 通道 uint8 check_sum; // 和校验 float data; // 数据 -}detector_parameter_struct; +}seekfree_assistant_parameter_struct; -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); #endif - diff --git a/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E02_uart_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.h b/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_detector.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E02_uart_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E02_uart_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E02_uart_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E02_uart_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E02_uart_demo/user/cpu0_main.c b/Example/E02_uart_demo/user/cpu0_main.c index b3c92be..ae07ee4 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_struct uart_data_fifo; +fifo_obj_struct uart_data_fifo; int core0_main(void) { @@ -99,7 +99,6 @@ int core0_main(void) // 此处编写用户代码 例如外设初始化代码等 cpu_wait_event_ready(); // 等待所有核心初始化完毕 - uart_rx_interrupt(UART_INDEX, 1); while (TRUE) { // 此处编写需要循环执行的代码 diff --git a/Example/E03_adc_demo/.cproject b/Example/E03_adc_demo/.cproject index 95c60a0..36f019f 100644 --- a/Example/E03_adc_demo/.cproject +++ b/Example/E03_adc_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E03_adc_demo/libraries/doc/version.txt b/Example/E03_adc_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E03_adc_demo/libraries/doc/version.txt +++ b/Example/E03_adc_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E03_adc_demo/libraries/zf_common/zf_common_debug.c b/Example/E03_adc_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E03_adc_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E03_adc_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.c b/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.h b/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E03_adc_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E03_adc_demo/libraries/zf_common/zf_common_typedef.h b/Example/E03_adc_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E03_adc_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E03_adc_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant.c b/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_detector.h b/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant.h similarity index 55% rename from Example/E04_pwm_demo/libraries/zf_device/zf_device_detector.h rename to Example/E03_adc_demo/libraries/zf_components/seekfree_assistant.h index ee2ea7e..d02abb1 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_detector.h +++ b/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant.h @@ -1,4 +1,4 @@ -/********************************************************************************************************************* +/*/********************************************************************************************************************* * TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 * Copyright (c) 2022 SEEKFREE 逐飞科技 * @@ -21,7 +21,7 @@ * 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 * 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) * -* 文件名称 zf_device_detector +* 文件名称 seekfree_assistant * 公司名称 成都逐飞科技有限公司 * 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 * 开发环境 ADS v1.9.4 @@ -30,67 +30,54 @@ * * 修改记录 * 日期 作者 备注 -* 2023-05-27 pudding first version +* 2023-11-29 pudding first version ********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ #include "zf_common_typedef.h" #include "zf_common_debug.h" // 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) // 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) // 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) // 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) // 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) // 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) // 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) // 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) // 摄像头类型枚举 typedef enum { // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; // 摄像头类型枚举 typedef enum @@ -100,7 +87,7 @@ typedef enum Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; +}seekfree_assistant_boundary_type_enum; typedef struct { @@ -108,8 +95,8 @@ typedef struct uint8 channel_num; // 高四位为功能字 低四位为通道数量 uint8 check_sum; // 和校验 uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; typedef struct @@ -120,7 +107,7 @@ typedef struct uint8 length; // 包长度(仅包含协议部分) uint16 image_width; // 图像宽度 uint16 image_height; // 图像高度 -}detector_camera_struct; +}seekfree_assistant_camera_struct; typedef struct @@ -130,19 +117,19 @@ typedef struct uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 uint8 length; // 包长度(仅包含协议部分) uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 + uint8 valid_flag; // 通道标识 uint8 reserve; // 保留 -}detector_camera_dot_struct; +}seekfree_assistant_camera_dot_struct; typedef struct { void *image_addr; // 摄像头地址 uint16 width; // 图像宽度 uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; typedef struct { @@ -151,23 +138,24 @@ typedef struct uint8 channel; // 通道 uint8 check_sum; // 和校验 float data; // 数据 -}detector_parameter_struct; +}seekfree_assistant_parameter_struct; -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); #endif - diff --git a/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E03_adc_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.h b/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_detector.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E03_adc_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E03_adc_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E03_adc_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E03_adc_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E03_adc_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E03_adc_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E04_pwm_demo/.cproject b/Example/E04_pwm_demo/.cproject index 85e6c6a..cb8b019 100644 --- a/Example/E04_pwm_demo/.cproject +++ b/Example/E04_pwm_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E04_pwm_demo/libraries/doc/version.txt b/Example/E04_pwm_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E04_pwm_demo/libraries/doc/version.txt +++ b/Example/E04_pwm_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E04_pwm_demo/libraries/zf_common/zf_common_debug.c b/Example/E04_pwm_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E04_pwm_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E04_pwm_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.c b/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.h b/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E04_pwm_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E04_pwm_demo/libraries/zf_common/zf_common_typedef.h b/Example/E04_pwm_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E04_pwm_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E04_pwm_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant.c b/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E02_uart_demo/libraries/zf_device/zf_device_detector.h b/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant.h similarity index 55% rename from Example/E02_uart_demo/libraries/zf_device/zf_device_detector.h rename to Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant.h index ee2ea7e..d02abb1 100644 --- a/Example/E02_uart_demo/libraries/zf_device/zf_device_detector.h +++ b/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant.h @@ -1,4 +1,4 @@ -/********************************************************************************************************************* +/*/********************************************************************************************************************* * TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库 * Copyright (c) 2022 SEEKFREE 逐飞科技 * @@ -21,7 +21,7 @@ * 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 * 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) * -* 文件名称 zf_device_detector +* 文件名称 seekfree_assistant * 公司名称 成都逐飞科技有限公司 * 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 * 开发环境 ADS v1.9.4 @@ -30,67 +30,54 @@ * * 修改记录 * 日期 作者 备注 -* 2023-05-27 pudding first version +* 2023-11-29 pudding first version ********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ #include "zf_common_typedef.h" #include "zf_common_debug.h" // 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) // 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) // 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) // 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) // 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) // 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) // 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) // 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) // 摄像头类型枚举 typedef enum { // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; // 摄像头类型枚举 typedef enum @@ -100,7 +87,7 @@ typedef enum Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; +}seekfree_assistant_boundary_type_enum; typedef struct { @@ -108,8 +95,8 @@ typedef struct uint8 channel_num; // 高四位为功能字 低四位为通道数量 uint8 check_sum; // 和校验 uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; typedef struct @@ -120,7 +107,7 @@ typedef struct uint8 length; // 包长度(仅包含协议部分) uint16 image_width; // 图像宽度 uint16 image_height; // 图像高度 -}detector_camera_struct; +}seekfree_assistant_camera_struct; typedef struct @@ -130,19 +117,19 @@ typedef struct uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 uint8 length; // 包长度(仅包含协议部分) uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 + uint8 valid_flag; // 通道标识 uint8 reserve; // 保留 -}detector_camera_dot_struct; +}seekfree_assistant_camera_dot_struct; typedef struct { void *image_addr; // 摄像头地址 uint16 width; // 图像宽度 uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; typedef struct { @@ -151,23 +138,24 @@ typedef struct uint8 channel; // 通道 uint8 check_sum; // 和校验 float data; // 数据 -}detector_parameter_struct; +}seekfree_assistant_parameter_struct; -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); #endif - diff --git a/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E04_pwm_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.h b/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_detector.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E04_pwm_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E04_pwm_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E04_pwm_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E04_pwm_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E04_pwm_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E05_pit_demo/.cproject b/Example/E05_pit_demo/.cproject index 3915da7..72f218a 100644 --- a/Example/E05_pit_demo/.cproject +++ b/Example/E05_pit_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E05_pit_demo/libraries/doc/version.txt b/Example/E05_pit_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E05_pit_demo/libraries/doc/version.txt +++ b/Example/E05_pit_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E05_pit_demo/libraries/zf_common/zf_common_debug.c b/Example/E05_pit_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E05_pit_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E05_pit_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.c b/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.h b/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E05_pit_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E05_pit_demo/libraries/zf_common/zf_common_typedef.h b/Example/E05_pit_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E05_pit_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E05_pit_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant.c b/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant.h b/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E05_pit_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.h b/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_detector.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_detector.h b/Example/E05_pit_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E05_pit_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E05_pit_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E05_pit_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E05_pit_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E05_pit_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E05_pit_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E06_exit_demo/.cproject b/Example/E06_exit_demo/.cproject index d53afaf..253a7a1 100644 --- a/Example/E06_exit_demo/.cproject +++ b/Example/E06_exit_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E06_exit_demo/libraries/doc/version.txt b/Example/E06_exit_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E06_exit_demo/libraries/doc/version.txt +++ b/Example/E06_exit_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E06_exit_demo/libraries/zf_common/zf_common_debug.c b/Example/E06_exit_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E06_exit_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E06_exit_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.c b/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.h b/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E06_exit_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E06_exit_demo/libraries/zf_common/zf_common_typedef.h b/Example/E06_exit_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E06_exit_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E06_exit_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant.c b/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant.h b/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E06_exit_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.h b/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_detector.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_detector.h b/Example/E06_exit_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E06_exit_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E06_exit_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E06_exit_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E06_exit_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E06_exit_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E06_exit_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E07_encoder_demo/.cproject b/Example/E07_encoder_demo/.cproject index 6a79e8b..9dfcf02 100644 --- a/Example/E07_encoder_demo/.cproject +++ b/Example/E07_encoder_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E07_encoder_demo/libraries/doc/version.txt b/Example/E07_encoder_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E07_encoder_demo/libraries/doc/version.txt +++ b/Example/E07_encoder_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E07_encoder_demo/libraries/zf_common/zf_common_debug.c b/Example/E07_encoder_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E07_encoder_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E07_encoder_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.c b/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.h b/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E07_encoder_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E07_encoder_demo/libraries/zf_common/zf_common_typedef.h b/Example/E07_encoder_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E07_encoder_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E07_encoder_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant.c b/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant.h b/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E07_encoder_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.h b/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_detector.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_detector.h b/Example/E07_encoder_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E07_encoder_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E07_encoder_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E07_encoder_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E07_encoder_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E07_encoder_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E08_eeprom_demo/.cproject b/Example/E08_eeprom_demo/.cproject index 4abbed4..c0fc9a3 100644 --- a/Example/E08_eeprom_demo/.cproject +++ b/Example/E08_eeprom_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E08_eeprom_demo/libraries/doc/version.txt b/Example/E08_eeprom_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E08_eeprom_demo/libraries/doc/version.txt +++ b/Example/E08_eeprom_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_debug.c b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.c b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.h b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_typedef.h b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E08_eeprom_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E08_eeprom_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant.c b/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant.h b/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E08_eeprom_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.h b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_detector.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_detector.h b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E08_eeprom_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E08_eeprom_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E09_timer_demo/.cproject b/Example/E09_timer_demo/.cproject index 38d38ce..67ba737 100644 --- a/Example/E09_timer_demo/.cproject +++ b/Example/E09_timer_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E09_timer_demo/libraries/doc/version.txt b/Example/E09_timer_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E09_timer_demo/libraries/doc/version.txt +++ b/Example/E09_timer_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E09_timer_demo/libraries/zf_common/zf_common_debug.c b/Example/E09_timer_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E09_timer_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E09_timer_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.c b/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.h b/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E09_timer_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E09_timer_demo/libraries/zf_common/zf_common_typedef.h b/Example/E09_timer_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E09_timer_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E09_timer_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant.c b/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant.h b/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E09_timer_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.h b/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_detector.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_detector.h b/Example/E09_timer_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E09_timer_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E09_timer_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E09_timer_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E09_timer_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E09_timer_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E09_timer_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E10_printf_debug_log_demo/.cproject b/Example/E10_printf_debug_log_demo/.cproject index c97264b..d834bb4 100644 --- a/Example/E10_printf_debug_log_demo/.cproject +++ b/Example/E10_printf_debug_log_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - 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 7faaf60..e4ebf19 100644 --- a/Example/E10_printf_debug_log_demo/libraries/doc/version.txt +++ b/Example/E10_printf_debug_log_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_debug.c b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.c b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.h b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_typedef.h b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant.c b/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant.h b/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E10_printf_debug_log_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.h b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_detector.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_detector.h b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E10_printf_debug_log_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E11_interrupt_priority_set_demo/.cproject b/Example/E11_interrupt_priority_set_demo/.cproject index 9717d97..fae5c4a 100644 --- a/Example/E11_interrupt_priority_set_demo/.cproject +++ b/Example/E11_interrupt_priority_set_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - 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 7faaf60..e4ebf19 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/doc/version.txt +++ b/Example/E11_interrupt_priority_set_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_debug.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_typedef.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_detector.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_detector.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E11_interrupt_priority_set_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E12_cpu1_handles_interrupts_demo/.cproject b/Example/E12_cpu1_handles_interrupts_demo/.cproject index 313b0b8..9101bd0 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/.cproject +++ b/Example/E12_cpu1_handles_interrupts_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - 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 7faaf60..e4ebf19 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/doc/version.txt +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_debug.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_typedef.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_detector.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_detector.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E12_cpu1_handles_interrupts_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E13_dual_core_demo/.cproject b/Example/E13_dual_core_demo/.cproject index bc772f0..ccac106 100644 --- a/Example/E13_dual_core_demo/.cproject +++ b/Example/E13_dual_core_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E13_dual_core_demo/libraries/doc/version.txt b/Example/E13_dual_core_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E13_dual_core_demo/libraries/doc/version.txt +++ b/Example/E13_dual_core_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_debug.c b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.c b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.h b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_typedef.h b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E13_dual_core_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E13_dual_core_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant.c b/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant.h b/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E13_dual_core_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.h b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_detector.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_detector.h b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E13_dual_core_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E13_dual_core_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E14_specifies_variable_or_code_location_demo/.cproject b/Example/E14_specifies_variable_or_code_location_demo/.cproject index 37e0f9d..4856f3a 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/.cproject +++ b/Example/E14_specifies_variable_or_code_location_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - 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 7faaf60..e4ebf19 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,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_debug.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_typedef.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_detector.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_detector.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E14_specifies_variable_or_code_location_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E15_fft_demo/.cproject b/Example/E15_fft_demo/.cproject index c5c8445..7d34c88 100644 --- a/Example/E15_fft_demo/.cproject +++ b/Example/E15_fft_demo/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - diff --git a/Example/E15_fft_demo/libraries/doc/version.txt b/Example/E15_fft_demo/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Example/E15_fft_demo/libraries/doc/version.txt +++ b/Example/E15_fft_demo/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Example/E15_fft_demo/libraries/zf_common/zf_common_debug.c b/Example/E15_fft_demo/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Example/E15_fft_demo/libraries/zf_common/zf_common_debug.c +++ b/Example/E15_fft_demo/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.c b/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.c +++ b/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.h b/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.h +++ b/Example/E15_fft_demo/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Example/E15_fft_demo/libraries/zf_common/zf_common_typedef.h b/Example/E15_fft_demo/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Example/E15_fft_demo/libraries/zf_common/zf_common_typedef.h +++ b/Example/E15_fft_demo/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant.c b/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant.h b/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant_interface.c b/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Example/E15_fft_demo/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.h b/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.h +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_detector.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_detector.h b/Example/E15_fft_demo/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_gps_tau1201.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_ov7725.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_ov7725.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_spi.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_spi.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_uart.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_uart.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Example/E15_fft_demo/libraries/zf_device/zf_device_wireless_uart.c b/Example/E15_fft_demo/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Example/E15_fft_demo/libraries/zf_device/zf_device_wireless_uart.c +++ b/Example/E15_fft_demo/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_delay.h b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_delay.h +++ b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_dma.c b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Example/E15_fft_demo/libraries/zf_driver/zf_driver_dma.c +++ b/Example/E15_fft_demo/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //------------------------------------------------------------------------------------------------------------------- diff --git a/Seekfree_TC264_Opensource_Library/.cproject b/Seekfree_TC264_Opensource_Library/.cproject index 47cc780..76c3e13 100644 --- a/Seekfree_TC264_Opensource_Library/.cproject +++ b/Seekfree_TC264_Opensource_Library/.cproject @@ -20,7 +20,7 @@ - - - @@ -104,7 +105,7 @@ - - - + diff --git a/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt b/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt index 7faaf60..e4ebf19 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt +++ b/Seekfree_TC264_Opensource_Library/libraries/doc/version.txt @@ -1,7 +1,10 @@ V3.2.4 优化延时函数为中断延时,关闭总中断则为普通延时 优化ips114屏幕的初始化时间,移除不必要的延时 - 修复串口错误中断的串口号异常的问题 + 修复串口错误中断的串口号异常的问题 + 追加更新: + 新增逐飞助手组件支持 + 修复fifo高频读写的冲突问题 V3.2.3 优化所有SPI通信屏幕(OLED除外)的通信方式,显示速率将提升一倍左右 修改串口的默认通信方式 @@ -11,7 +14,6 @@ V3.2.1 flash新增写入时的是否擦除当前页的判断 防止用户因使用不规范导致flash使用报错 V3.2.0 新增wifi spi模块驱动文件 - 新增detector上位机API接口 新增四类总线报错提醒,并添加断言保护 zf_device_type 新增 ToF 类别控制 新增 ToF 模块 DL1B diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_debug.c b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_debug.c index ea153a2..52c623d 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_debug.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_debug.c @@ -46,7 +46,7 @@ static volatile uint8 zf_debug_assert_enable = 1; #if DEBUG_UART_USE_INTERRUPT // 如果启用 debug uart 接收中断 uint8 debug_uart_buffer[DEBUG_RING_BUFFER_LEN]; // 数据存放数组 uint8 debug_uart_data; -fifo_struct debug_uart_fifo; +fifo_obj_struct debug_uart_fifo; #endif //------------------------------------------------------------------------------------------------------------------- diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.c b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.c index 3689a2a..b010d3e 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.c @@ -30,9 +30,11 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ +#include "zf_common_debug.h" #include "zf_common_fifo.h" //------------------------------------------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_head_offset (fifo_struct *fifo, uint32 offset) +static void fifo_head_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->head += offset; @@ -61,7 +63,7 @@ static void fifo_head_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- -static void fifo_end_offset (fifo_struct *fifo, uint32 offset) +static void fifo_end_offset (fifo_obj_struct *fifo, uint32 offset) { fifo->end += offset; @@ -78,34 +80,28 @@ static void fifo_end_offset (fifo_struct *fifo, uint32 offset) // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_clear (fifo_struct *fifo) +fifo_state_enum fifo_clear (fifo_obj_struct *fifo) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; - break; - } - fifo->execution |= FIFO_CLEAR; - fifo->head = 0; - fifo->end = 0; - fifo->size = fifo->max; - +// if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 +// { +// return_state = FIFO_RESET_UNDO; // 重置操作未完成 +// break; +// } + fifo->execution |= FIFO_RESET; // 重置操作置位 + fifo->head = 0; // 重置 FIFO 所有数值复位 + fifo->end = 0; // 重置 FIFO 所有数值复位 + fifo->size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { - case FIFO_DATA_8BIT: - memset(fifo->buffer, 0, fifo->max); - break; - case FIFO_DATA_16BIT: - memset(fifo->buffer, 0, fifo->max * 2); - break; - case FIFO_DATA_32BIT: - memset(fifo->buffer, 0, fifo->max * 4); - break; + case FIFO_DATA_8BIT: memset(fifo->buffer, 0, fifo->max); break; + case FIFO_DATA_16BIT: memset(fifo->buffer, 0, fifo->max * 2); break; + case FIFO_DATA_32BIT: memset(fifo->buffer, 0, fifo->max * 4); break; } - fifo->execution &= ~FIFO_CLEAR; + fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } @@ -117,9 +113,10 @@ fifo_state_enum fifo_clear (fifo_struct *fifo) // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -uint32 fifo_used (fifo_struct *fifo) +uint32 fifo_used (fifo_obj_struct *fifo) { - return (fifo->max - fifo->size); + zf_assert(fifo != NULL); + return (fifo->max - fifo->size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- @@ -130,41 +127,36 @@ uint32 fifo_used (fifo_struct *fifo) // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->size) // 剩余空间足够装下本次数据 { switch(fifo->type) { - case FIFO_DATA_8BIT: - ((uint8 *)fifo->buffer)[fifo->head] = dat & 0xFF; - break; - case FIFO_DATA_16BIT: - ((uint16 *)fifo->buffer)[fifo->head] = dat & 0xFFFF; - break; - case FIFO_DATA_32BIT: - ((uint32 *)fifo->buffer)[fifo->head] = dat; - break; + case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = (uint8)dat; break; + case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = (uint16)dat; break; + case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->size -= 1; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -179,26 +171,27 @@ fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } - if(FIFO_WRITE & fifo->execution) + if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { - return_state = FIFO_WRITE_UNDO; + return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } - fifo->execution |= FIFO_WRITE; + fifo->execution |= FIFO_WRITE; // 写入操作置位 - if(length <= fifo->size) // 剩余空间足够装下本次数据 + if(length <= fifo->size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 @@ -207,6 +200,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, temp_length); // 拷贝第一段数据 @@ -216,8 +210,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint8 *)dat)[temp_length]), length - temp_length); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 @@ -227,8 +222,9 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 @@ -238,7 +234,7 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 - break; + }break; } } else @@ -246,35 +242,36 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) switch(fifo->type) { case FIFO_DATA_8BIT: + { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_16BIT: + { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; case FIFO_DATA_32BIT: + { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 - break; + }break; } -// memcpy(&fifo->buffer[fifo->head], dat, length); // 一次完整写入 -// fifo_head_offset(fifo, length); // 头指针偏移 } fifo->size -= length; // 缓冲区剩余长度减小 } else { - return_state = FIFO_SPACE_NO_ENOUGH; + return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } - fifo->execution &= ~FIFO_WRITE; + fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; @@ -289,51 +286,54 @@ fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { - return_state = FIFO_BUFFER_NULL; - break; + return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } - fifo->execution |= FIFO_READ; - - if(1 > fifo_used(fifo)) + else { - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - switch(fifo->type) - { - case FIFO_DATA_8BIT: - *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_16BIT: - *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; - break; - case FIFO_DATA_32BIT: - *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; - break; - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - return_state = FIFO_CLEAR_UNDO; + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + if(1 > fifo_used(fifo)) + { + return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 + break; // 直接退出操作 + } + + fifo->execution |= FIFO_READ; // 读操作置位 + switch(fifo->type) + { + case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; + case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 - fifo->size += 1; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += 1; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -348,75 +348,89 @@ fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_ // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 - if(*length <= temp_length) // 足够一次性读取完毕 - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); - break; - } } else { - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 + if(*length <= temp_length) // 足够一次性读取完毕 + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), *length * 2); break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), *length * 4); break; + } + } + else + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, *length - temp_length); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 - fifo->size += *length; - fifo->execution &= ~FIFO_CLEAR; + fifo->size += *length; // 释放对应长度空间 + fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -433,75 +447,86 @@ fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { - fifo_state_enum return_state = FIFO_SUCCESS; - uint32 temp_length; + zf_assert(NULL != fifo); + zf_assert(NULL != length); + fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 + uint32 temp_length = 0; + uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; - break; - } - fifo->execution |= FIFO_READ; - - if(*length > fifo_used(fifo)) - { - *length = (fifo->max - fifo->size); // 纠正读取的长度 - return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 - } - - if((fifo->head > fifo->end) || (fifo->head >= *length)) - { - switch(fifo->type) - { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4); - break; - } } else { - temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 - switch(fifo->type) + if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { - case FIFO_DATA_8BIT: - memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); - memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); - break; - case FIFO_DATA_16BIT: - memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); - memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); - break; - case FIFO_DATA_32BIT: - memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); - memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); - break; - } - } - - if(flag == FIFO_READ_AND_CLEAN) // 如果选择读取并更改 FIFO 状态 - { - if(FIFO_CLEAR & fifo->execution) - { - return_state = FIFO_CLEAR_UNDO; + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } - fifo->execution |= FIFO_CLEAR; - fifo_end_offset(fifo, (fifo->max - fifo->size)); - fifo->size = fifo->max; - fifo->execution &= ~FIFO_CLEAR; + + fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 + if(*length > fifo_data_length) // 判断长度是否足够 + { + *length = fifo_data_length; // 纠正读取的长度 + return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 + if(0 == fifo_data_length) // 如果没有数据 就直接退出 + { + fifo->execution &= ~FIFO_READ; // 读操作复位 + break; + } + } + + fifo->execution |= FIFO_READ; // 读操作置位 + if((fifo->head > fifo->end) || (fifo->head >= *length)) + { + switch(fifo->type) + { + case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), *length); break; + case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), *length * 2);break; + case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), *length * 4);break; + } + } + else + { + temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 + switch(fifo->type) + { + case FIFO_DATA_8BIT: + { + memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), temp_length); + memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length)); + }break; + case FIFO_DATA_16BIT: + { + memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); + memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 2); + }break; + case FIFO_DATA_32BIT: + { + memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); + memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (*length - temp_length) * 4); + }break; + } + } + fifo->execution &= ~FIFO_READ; // 读操作复位 + } + + if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 + { + if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 + { + return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 + break; + } + fifo_clear(fifo); } }while(0); - fifo->execution &= FIFO_READ; return return_state; } @@ -516,23 +541,19 @@ fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *len // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size) { - fifo_state_enum return_value = FIFO_SUCCESS; + zf_assert(NULL != fifo); + fifo_state_enum return_state = FIFO_SUCCESS; do { - if(NULL == buffer_addr) - { - return_value = FIFO_BUFFER_NULL; - break; - } - fifo->buffer = buffer_addr; - fifo->execution = FIFO_IDLE; - fifo->type = type; - fifo->head = 0; - fifo->end = 0; - fifo->size = size; - fifo->max = size; + fifo->buffer = buffer_addr; + fifo->execution = FIFO_IDLE; + fifo->type = type; + fifo->head = 0; + fifo->end = 0; + fifo->size = size; + fifo->max = size; }while(0); - return return_value; + return return_state; } diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.h b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.h index f28d7ac..5cc7668 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_fifo.h @@ -30,7 +30,8 @@ * * 修改记录 * 日期 作者 备注 -* 2022-09-15 pudding first version +* 2022-08-10 Teternal first version +* 2023-12-06 Teternal 更新操作逻辑 修复无数据读取时异常的操作 ********************************************************************************************************************/ #ifndef _zf_common_fifo_h_ @@ -40,56 +41,67 @@ typedef enum { - FIFO_SUCCESS, + FIFO_SUCCESS, // FIFO 操作成功 - FIFO_WRITE_UNDO, - FIFO_CLEAR_UNDO, - FIFO_BUFFER_NULL, - FIFO_SPACE_NO_ENOUGH, - FIFO_DATA_NO_ENOUGH, -}fifo_state_enum; + FIFO_RESET_UNDO, // FIFO 重置操作未执行 + FIFO_CLEAR_UNDO, // FIFO 清空操作未执行 + FIFO_BUFFER_NULL, // FIFO 用户缓冲区异常 + FIFO_WRITE_UNDO, // FIFO 写入操作未执行 + FIFO_SPACE_NO_ENOUGH, // FIFO 写入操作 缓冲区空间不足 + FIFO_READ_UNDO, // FIFO 读取操作未执行 + FIFO_DATA_NO_ENOUGH, // FIFO 读取操作 数据长度不足 +}fifo_state_enum; // FIFO 操作结果 + +// 操作逻辑 +// 整体重置操作 将会强制清空 FIFO 谨慎使用 +// 数据写入操作 不能在重置以及写入操作时进行 +// 顺序读取操作 不能在清空和重置操作时进行 +// 尾部读取操作 不能在清空和重置以及写入操作时进行 +// 读取清空操作 不能在清空和重置以及读取操作时进行 +// 这是为了防止中断嵌套导致数据混乱 +typedef enum +{ + FIFO_IDLE = 0x00, // 空闲状态 + + FIFO_RESET = 0x01, // 正在执行重置缓冲区 + FIFO_CLEAR = 0x02, // 正在执行清空缓冲区 + FIFO_WRITE = 0x04, // 正在执行写入缓冲区 + FIFO_READ = 0x08, // 正在执行读取缓冲区 +}fifo_execution_enum; // FIFO 操作状态 为嵌套使用预留 无法完全避免误操作 typedef enum { - FIFO_IDLE = 0x00, - FIFO_CLEAR = 0x01, - FIFO_WRITE = 0x02, - FIFO_READ = 0x04, -}fifo_execution_enum; - -typedef enum -{ - FIFO_READ_AND_CLEAN, - FIFO_READ_ONLY, + FIFO_READ_AND_CLEAN, // FIFO 读操作模式 读取后清空释放对应缓冲区 + FIFO_READ_ONLY, // FIFO 读操作模式 仅读取 }fifo_operation_enum; typedef enum { - FIFO_DATA_8BIT, - FIFO_DATA_16BIT, - FIFO_DATA_32BIT, + FIFO_DATA_8BIT, // FIFO 数据位宽 8bit + FIFO_DATA_16BIT, // FIFO 数据位宽 16bit + FIFO_DATA_32BIT, // FIFO 数据位宽 32bit }fifo_data_type_enum; typedef struct { uint8 execution; // 执行步骤 fifo_data_type_enum type; // 数据类型 - void *buffer; // 缓存指针 + void *buffer; // 缓存指针 uint32 head; // 缓存头指针 总是指向空的缓存 uint32 end; // 缓存尾指针 总是指向非空缓存(缓存全空除外) uint32 size; // 缓存剩余大小 uint32 max; // 缓存总大小 -}fifo_struct; +}fifo_obj_struct; -fifo_state_enum fifo_clear (fifo_struct *fifo); -uint32 fifo_used (fifo_struct *fifo); +fifo_state_enum fifo_clear (fifo_obj_struct *fifo); +uint32 fifo_used (fifo_obj_struct *fifo); -fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat); -fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length); -fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag); -fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_write_element (fifo_obj_struct *fifo, uint32 dat); +fifo_state_enum fifo_write_buffer (fifo_obj_struct *fifo, void *dat, uint32 length); +fifo_state_enum fifo_read_element (fifo_obj_struct *fifo, void *dat, fifo_operation_enum flag); +fifo_state_enum fifo_read_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); +fifo_state_enum fifo_read_tail_buffer (fifo_obj_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag); -fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); +fifo_state_enum fifo_init (fifo_obj_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 size); #endif 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 a048cbc..aa06ef8 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 @@ -84,7 +84,6 @@ #include "zf_device_bluetooth_ch9141.h" #include "zf_device_gps_tau1201.h" #include "zf_device_camera.h" -#include "zf_device_detector.h" #include "zf_device_dl1a.h" #include "zf_device_dl1b.h" #include "zf_device_icm20602.h" @@ -107,6 +106,10 @@ #include "zf_device_wireless_uart.h" //===================================================外接设备驱动层=================================================== +//====================================================应用组件层==================================================== +#include "seekfree_assistant.h" +//====================================================应用组件层==================================================== + //=====================================================用户层====================================================== //=====================================================用户层====================================================== diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_typedef.h b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_typedef.h index 4a98083..bd09f30 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_typedef.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_common/zf_common_typedef.h @@ -72,6 +72,8 @@ typedef volatile int64 vint64; #define ZF_TRUE (1) #define ZF_FALSE (0) + +#define ZF_WEAK __attribute__((weak)) //=================================================== 类型定义 =================================================== #endif diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant.c b/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant.c new file mode 100644 index 0000000..a196e10 --- /dev/null +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant.c @@ -0,0 +1,436 @@ +/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#include "zf_common_fifo.h" +#include "seekfree_assistant.h" + +seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +static seekfree_assistant_camera_struct seekfree_assistant_camera_data; // 图像上位机协议数据 +static seekfree_assistant_camera_dot_struct seekfree_assistant_camera_dot_data; // 图像上位机打点协议数据 +static seekfree_assistant_camera_buffer_struct seekfree_assistant_camera_buffer; // 图像以及边界缓冲区信息 + +static fifo_obj_struct seekfree_assistant_fifo; +static uint8 seekfree_assistant_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE]; // 数据存放数组 +float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 保存接收到的参数 +vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT] = {0}; // 参数更新标志位 + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手求和函数 +// 参数说明 *buffer 需要校验的数据地址 +// 参数说明 length 校验长度 +// 返回参数 uint8 和值 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +static uint8 seekfree_assistant_sum (uint8 *buffer, uint32 length) +{ + uint8 temp_sum = 0; + + while(length--) + { + temp_sum += *buffer++; + } + + return temp_sum; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像发送函数 +// 参数说明 camera_type 摄像头类型 +// 参数说明 *image_addr 图像首地址 +// 参数说明 boundary_num 图像中包含边界数量 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_data_send (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) +{ + uint32 image_size = 0; + + seekfree_assistant_camera_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_data.function = SEEKFREE_ASSISTANT_CAMERA_FUNCTION; + seekfree_assistant_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; + // 写入包长度信息,仅包含协议部分 + seekfree_assistant_camera_data.length = sizeof(seekfree_assistant_camera_struct); + seekfree_assistant_camera_data.image_width = width; + seekfree_assistant_camera_data.image_height = height; + + // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_data, sizeof(seekfree_assistant_camera_struct)); + + // 根据摄像头类型计算图像大小 + switch(camera_type) + { + case SEEKFREE_ASSISTANT_OV7725_BIN: + { + image_size = width * height / 8; + }break; + + case SEEKFREE_ASSISTANT_MT9V03X: + { + image_size = width * height; + }break; + + case SEEKFREE_ASSISTANT_SCC8660: + { + image_size = width * height * 2; + }break; + } + + // 发送图像数据 + if(NULL != image_addr) + { + seekfree_assistant_transfer(image_addr, image_size); + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 图像边线绘制函数 +// 参数说明 boundary_id 边线ID +// 参数说明 dot_num 点数量 +// 参数说明 *dot_x 横坐标数据首地址 +// 参数说明 *dot_y 纵坐标数据首地址 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_dot_send (seekfree_assistant_camera_buffer_struct *buffer) +{ + uint8 i; + uint16 dot_bytes = 0; // 点字节数量 + + dot_bytes = seekfree_assistant_camera_dot_data.dot_num; + + if(seekfree_assistant_camera_dot_data.dot_type & (1 << 5)) + { + dot_bytes *= 2; + } + + + // 首先发送帧头、功能、边界编号、坐标长度、点个数 + seekfree_assistant_transfer((const uint8 *)&seekfree_assistant_camera_dot_data, sizeof(seekfree_assistant_camera_dot_struct)); + + for(i=0; i < SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY; i++) + { + // 判断是否发送横坐标数据 + if(NULL != buffer->boundary_x[i]) + { + seekfree_assistant_transfer((const uint8 *)buffer->boundary_x[i], dot_bytes); + } + + // 判断是否发送纵坐标数据 + if(NULL != buffer->boundary_y[i]) + { + // 如果没有纵坐标数据,则表示每一行只有一个边界 + // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 + seekfree_assistant_transfer((const uint8 *)buffer->boundary_y[i], dot_bytes); + } + } + +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 虚拟示波器发送函数 +// 参数说明 *seekfree_assistant_oscilloscope 示波器数据结构体 +// 返回参数 void +// 使用示例 seekfree_assistant_oscilloscope_send(&seekfree_assistant_oscilloscope_data); +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope) +{ + uint8 packet_size; + + // 将高四位清空 + seekfree_assistant_oscilloscope->channel_num &= 0x0f; + + zf_assert(SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT >= seekfree_assistant_oscilloscope->channel_num); + + // 帧头 + seekfree_assistant_oscilloscope->head = SEEKFREE_ASSISTANT_SEND_HEAD; + + // 写入包长度信息 + packet_size = sizeof(seekfree_assistant_oscilloscope_struct) - (SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT - seekfree_assistant_oscilloscope->channel_num) * 4; + seekfree_assistant_oscilloscope->length = packet_size; + + // 写入功能字与通道数量 + seekfree_assistant_oscilloscope->channel_num |= SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE; + + // 和校验计算 + seekfree_assistant_oscilloscope->check_sum = 0; + seekfree_assistant_oscilloscope->check_sum = seekfree_assistant_sum((uint8 *)seekfree_assistant_oscilloscope, packet_size); + + // 数据在调用本函数之前,由用户将需要发送的数据写入seekfree_assistant_oscilloscope_data.data[] + + seekfree_assistant_transfer((const uint8 *)seekfree_assistant_oscilloscope, packet_size); +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像信息配置函数 +// 参数说明 camera_type 图像类型 +// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 +// 参数说明 width 图像宽度 +// 参数说明 height 图像高度 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) +{ + seekfree_assistant_camera_dot_data.head = SEEKFREE_ASSISTANT_SEND_HEAD; + seekfree_assistant_camera_dot_data.function = SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION; + // 写入包长度信息 + seekfree_assistant_camera_dot_data.length = sizeof(seekfree_assistant_camera_dot_struct); + + seekfree_assistant_camera_buffer.camera_type = camera_type; + seekfree_assistant_camera_buffer.image_addr = image_addr; + seekfree_assistant_camera_buffer.width = width; + seekfree_assistant_camera_buffer.height = height; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手图像边线发送配置函数 +// 参数说明 boundary_type 边界类型 +// 参数说明 dot_num 一条边界有多少个点 +// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 +// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 +// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 +// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 +// 返回参数 void +// 使用示例 seekfree_assistant_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 +// 使用示例 seekfree_assistant_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 +// 使用示例 seekfree_assistant_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 +// 备注信息 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) +{ + uint8 i = 0; + uint8 boundary_num = 0; + uint8 boundary_data_type = 0; + + // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用seekfree_assistant_camera_config设置好图像信息 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_dot_data.dot_num = dot_num; + seekfree_assistant_camera_dot_data.valid_flag = 0; + for(i = 0; i < 3; i++) + { + seekfree_assistant_camera_buffer.boundary_x[i] = NULL; + seekfree_assistant_camera_buffer.boundary_y[i] = NULL; + } + + switch(boundary_type) + { + case X_BOUNDARY: + { + if(NULL != dot_x1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x1; + } + if(NULL != dot_x2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x2; + } + if(NULL != dot_x3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i++] = dot_x3; + } + + if(255 < seekfree_assistant_camera_buffer.height) + { + boundary_data_type = 1; + } + }break; + + case Y_BOUNDARY: + { + if(NULL != dot_y1) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if(NULL != dot_y2) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if(NULL != dot_y3) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if(255 < seekfree_assistant_camera_buffer.width) + { + boundary_data_type = 1; + } + }break; + + case XY_BOUNDARY: + { + if((NULL != dot_x1) && (NULL != dot_y1)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 0; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x1; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y1; + } + if((NULL != dot_x2) && (NULL != dot_y2)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 1; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x2; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y2; + } + if((NULL != dot_x3) && (NULL != dot_y3)) + { + boundary_num++; + seekfree_assistant_camera_dot_data.valid_flag |= 1 << 2; + seekfree_assistant_camera_buffer.boundary_x[i] = dot_x3; + seekfree_assistant_camera_buffer.boundary_y[i++] = dot_y3; + } + + if((255 < seekfree_assistant_camera_buffer.width) || (255 < seekfree_assistant_camera_buffer.height)) + { + boundary_data_type = 1; + } + }break; + + case NO_BOUNDARY:break; + } + + seekfree_assistant_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送摄像头图像 +// 参数说明 void +// 返回参数 void +// 使用示例 +// 备注信息 在调用图像发送函数之前,请务必调用一次seekfree_assistant_camera_config函数,将对应的参数设置好 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_camera_send (void) +{ + // 检查图像发送缓冲区是否准备就绪 + zf_assert(0 != seekfree_assistant_camera_buffer.camera_type); + + seekfree_assistant_camera_data_send(seekfree_assistant_camera_buffer.camera_type, seekfree_assistant_camera_buffer.image_addr, seekfree_assistant_camera_dot_data.dot_type & 0x0f, seekfree_assistant_camera_buffer.width, seekfree_assistant_camera_buffer.height); + + if(seekfree_assistant_camera_dot_data.dot_type & 0x0f) + { + seekfree_assistant_camera_dot_send(&seekfree_assistant_camera_buffer); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手解析接收到的数据 +// 参数说明 void +// 返回参数 void +// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_assistant_data_analysis (void) +{ + uint8 temp_sum; + uint32 read_length; + seekfree_assistant_parameter_struct *receive_packet; + + // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 + uint32 temp_buffer[SEEKFREE_ASSISTANT_BUFFER_SIZE / 4]; + + // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 + read_length = seekfree_assistant_receive((uint8 *)temp_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); + if(read_length) + { + // 将读取到的数据写入FIFO + fifo_write_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, read_length); + } + + + while(sizeof(seekfree_assistant_parameter_struct) <= fifo_used(&seekfree_assistant_fifo)) + { + read_length = sizeof(seekfree_assistant_parameter_struct); + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); + + if(SEEKFREE_ASSISTANT_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) + { + // 没有帧头则从FIFO中去掉第一个数据 + read_length = 1; + } + else + { + // 找到帧头 + receive_packet = (seekfree_assistant_parameter_struct *)temp_buffer; + temp_sum = receive_packet->check_sum; + receive_packet->check_sum = 0; + if(temp_sum == seekfree_assistant_sum((uint8 *)temp_buffer, sizeof(seekfree_assistant_parameter_struct))) + { + // 和校验成功保存数据 + seekfree_assistant_parameter[receive_packet->channel - 1] = receive_packet->data; + seekfree_assistant_parameter_update_flag[receive_packet->channel - 1] = 1; + } + else + { + read_length = 1; + } + } + + + // 丢弃无需使用的数据 + fifo_read_buffer(&seekfree_assistant_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_AND_CLEAN); + } +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手 初始化 +// 参数说明 +// 返回参数 void +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK void seekfree_assistant_init () +{ + fifo_init(&seekfree_assistant_fifo, FIFO_DATA_8BIT, seekfree_assistant_buffer, SEEKFREE_ASSISTANT_BUFFER_SIZE); +} + + diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant.h b/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant.h new file mode 100644 index 0000000..d02abb1 --- /dev/null +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant.h @@ -0,0 +1,161 @@ +/*/********************************************************************************************************************* +* 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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ +#ifndef _seekfree_assistant_h_ +#define _seekfree_assistant_h_ + + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" + +// 定义接收FIFO大小 +#define SEEKFREE_ASSISTANT_BUFFER_SIZE ( 0x80 ) + +// 定义示波器的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT ( 0x08 ) + +// 定义参数调试的最大通道数量 +#define SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT ( 0x08 ) + +// 定义图像边线最大数量 +#define SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY ( 0x08 ) + +// 单片机往上位机发送的帧头 +#define SEEKFREE_ASSISTANT_SEND_HEAD ( 0xAA ) + +// 摄像头类 +#define SEEKFREE_ASSISTANT_CAMERA_FUNCTION ( 0x02 ) +#define SEEKFREE_ASSISTANT_CAMERA_DOT_FUNCTION ( 0x03 ) +#define SEEKFREE_ASSISTANT_CAMERA_OSCILLOSCOPE ( 0x10 ) + +// 上位机往单片机发送的帧头 +#define SEEKFREE_ASSISTANT_RECEIVE_HEAD ( 0x55 ) + +// 参数设置类 +#define SEEKFREE_ASSISTANT_RECEIVE_SET_PARAMETER ( 0x20 ) + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + SEEKFREE_ASSISTANT_OV7725_BIN = 1, + SEEKFREE_ASSISTANT_MT9V03X, + SEEKFREE_ASSISTANT_SCC8660, + + // 按照图像类型定义 + SEEKFREE_ASSISTANT_BINARY = 1, + SEEKFREE_ASSISTANT_GRAY, + SEEKFREE_ASSISTANT_RGB565, +}seekfree_assistant_image_type_enum; + +// 摄像头类型枚举 +typedef enum +{ + // 按照摄像头型号定义 + X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 + Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 + XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 + NO_BOUNDARY, // 发送的图像中没有边线信息 +}seekfree_assistant_boundary_type_enum; + +typedef struct +{ + uint8 head; // 帧头 + uint8 channel_num; // 高四位为功能字 低四位为通道数量 + uint8 check_sum; // 和校验 + uint8 length; // 包长度 + float data[SEEKFREE_ASSISTANT_SET_OSCILLOSCOPE_COUNT]; // 通道数据 +}seekfree_assistant_oscilloscope_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 + uint8 length; // 包长度(仅包含协议部分) + uint16 image_width; // 图像宽度 + uint16 image_height; // 图像高度 +}seekfree_assistant_camera_struct; + + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 + uint8 length; // 包长度(仅包含协议部分) + uint16 dot_num; // 画点数量 + uint8 valid_flag; // 通道标识 + uint8 reserve; // 保留 +}seekfree_assistant_camera_dot_struct; + +typedef struct +{ + void *image_addr; // 摄像头地址 + uint16 width; // 图像宽度 + uint16 height; // 图像高度 + seekfree_assistant_image_type_enum camera_type; // 摄像头类型 + void *boundary_x[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 + void *boundary_y[SEEKFREE_ASSISTANT_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 +}seekfree_assistant_camera_buffer_struct; + +typedef struct +{ + uint8 head; // 帧头 + uint8 function; // 功能字 + uint8 channel; // 通道 + uint8 check_sum; // 和校验 + float data; // 数据 +}seekfree_assistant_parameter_struct; + + +extern seekfree_assistant_oscilloscope_struct seekfree_assistant_oscilloscope_data; // 虚拟示波器数据 +extern float seekfree_assistant_parameter[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 保存接收到的参数 +extern vuint8 seekfree_assistant_parameter_update_flag[SEEKFREE_ASSISTANT_SET_PARAMETR_COUNT]; // 参数更新标志位 + +uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length); +uint32 seekfree_assistant_receive (uint8 *buff, uint32 length); + +void seekfree_assistant_oscilloscope_send (seekfree_assistant_oscilloscope_struct *seekfree_assistant_oscilloscope); + +void seekfree_assistant_camera_information_config (seekfree_assistant_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); +void seekfree_assistant_camera_boundary_config (seekfree_assistant_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); +void seekfree_assistant_camera_send (void); + +void seekfree_assistant_data_analysis (void); +void seekfree_assistant_init (void); + + +#endif diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant_interface.c b/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant_interface.c new file mode 100644 index 0000000..99dbeef --- /dev/null +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_components/seekfree_assistant_interface.c @@ -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 文件 +* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) +* +* 文件名称 seekfree_assistant_interface +* 公司名称 成都逐飞科技有限公司 +* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 +* 开发环境 ADS v1.9.4 +* 适用平台 TC264D +* 店铺链接 https://seekfree.taobao.com/ +* +* 修改记录 +* 日期 作者 备注 +* 2023-11-29 pudding first version +********************************************************************************************************************/ + +#include "zf_common_typedef.h" +#include "zf_common_debug.h" +#include "seekfree_assistant.h" + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手发送函数 +// 参数说明 *buff 需要发送的数据地址 +// 参数说明 length 需要发送的长度 +// 返回参数 uint32 剩余未发送数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_transfer (const uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_send_buffer(buff, length); + + return len; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 逐飞助手接收数据函数 +// 参数说明 *buff 需要接收的数据地址 +// 参数说明 length 要接收的数据最大长度 +// 返回参数 uint32 接收到的数据长度 +// 使用示例 +//------------------------------------------------------------------------------------------------------------------- +ZF_WEAK uint32 seekfree_assistant_receive (uint8 *buff, uint32 length) +{ + uint32 len = 0; + + len = debug_read_ring_buffer(buff, length); + + return len; +} + + diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_bluetooth_ch9141.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_bluetooth_ch9141.c index e61a3fd..500bccb 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_bluetooth_ch9141.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_bluetooth_ch9141.c @@ -54,7 +54,7 @@ #include "zf_device_camera.h" #include "zf_device_bluetooth_ch9141.h" -static fifo_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 +static fifo_obj_struct bluetooth_ch9141_fifo; // fifo缓冲区结构体定义 static uint8 bluetooth_ch9141_buffer[BLUETOOTH_CH9141_BUFFER_SIZE]; // 数据存放数组 static uint8 bluetooth_ch9141_data = 0; // 数据临时存放变量 diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.c index 69f947c..84c7aa0 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.c @@ -45,7 +45,7 @@ #include "zf_device_camera.h" -fifo_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 +fifo_obj_struct camera_receiver_fifo; // 定义摄像头接收数据fifo结构体 uint8 camera_receiver_buffer[CAMERA_RECEIVER_BUFFER_SIZE]; // 定义摄像头接收数据缓冲区 uint8 camera_send_image_frame_header[4] = {0x00, 0xFF, 0x01, 0x01}; // 定义摄像头数据发送到上位机的帧头 diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.h b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.h index 5cfd10f..58efb06 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_camera.h @@ -44,7 +44,7 @@ //=================================================摄像头公共库 基本配置================================================ #define CAMERA_RECEIVER_BUFFER_SIZE (8) // 定义摄像头接收数据缓冲区大小 -extern fifo_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 +extern fifo_obj_struct camera_receiver_fifo; // 声明摄像头接收数据fifo结构体 extern uint8 camera_send_image_frame_header[4]; // 声明摄像头数据发送到上位机的帧头 //=================================================摄像头公共库 基本配置================================================ diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_detector.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_detector.c deleted file mode 100644 index 7a04b7b..0000000 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_detector.c +++ /dev/null @@ -1,628 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#include "zf_driver_uart.h" -#include "zf_common_fifo.h" -#include "zf_device_wireless_uart.h" -#include "zf_device_bluetooth_ch9141.h" -#include "zf_device_wifi_uart.h" -#include "zf_device_wifi_spi.h" - -#include "zf_device_detector.h" - - -typedef uint32 (*detector_transfer_callback_function) (const uint8 *buff, uint32 length); -typedef uint32 (*detector_receive_callback_function) (uint8 *buff, uint32 length); - -detector_transfer_type_enum detector_transfer_type; // 数据传输方式 - -detector_transfer_callback_function detector_transfer_callback; // 数据发送函数指针 -detector_receive_callback_function detector_receive_callback; // 数据接收函数指针 - -detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -static detector_camera_struct detector_camera_data; // 图像上位机协议数据 -static detector_camera_dot_struct detector_camera_dot_data; // 图像上位机打点协议数据 -static detector_camera_buffer_struct detector_camera_buffer; // 图像以及边界缓冲区信息 - -static fifo_struct detector_fifo; -static uint8 detector_buffer[DETECTOR_BUFFER_SIZE]; // 数据存放数组 -float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口发送函数 -//// 参数说明 *buff 需要发送的数据地址 -//// 参数说明 length 需要发送的长度 -//// 返回参数 uint32 剩余未发送数据长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_transfer (const uint8 *buff, uint32 length) -//{ -// uart_write_buffer(DEBUG_UART_INDEX, buff, length); -// return 0; -//} - -////------------------------------------------------------------------------------------------------------------------- -//// 函数简介 滴答客有线串口接收函数 -//// 参数说明 *buff 需要接收的数据地址 -//// 参数说明 length 需要接收的长度 -//// 返回参数 uint32 实际接收长度 -//// 使用示例 -////------------------------------------------------------------------------------------------------------------------- -//uint32 detector_debug_uart_receive (uint8 *buff, uint32 length) -//{ -// return debug_read_ring_buffer(buff, length); -//} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义字节发送函数 -// 参数说明 data 需要发送的数据地址 -// 返回参数 uint8 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_custom_write_byte(const uint8 data) -{ - // 自行实现字节发送 - - return 0; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义发送函数 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 如果数据传输方式并不在支持范围则可以自行实现 -//------------------------------------------------------------------------------------------------------------------- -uint32 detector_custom_transfer (const uint8 *buff, uint32 length) -{ - uint32 send_length; - send_length = length; - - while(send_length--) - { - detector_custom_write_byte(*buff); - buff++; - } - - return send_length; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按字节接收 -// 参数说明 *data 需要发送的数据地址 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive_byte (uint8 data) -{ - uint8 return_state = 0; - // 自行实现字节发送 - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, &data, 1)) - { - return_state = 1; - } - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客自定义接收函数 按数组接收 -// 参数说明 *buff 需要发送的数据地址 -// 参数说明 length 需要发送的长度 -// 返回参数 uint8 0:接收成功 1:接收失败 -// 注意事项 detector_custom_receive_byte 与 detector_custom_receive函数 只需要调用其中一个函数即可 -//------------------------------------------------------------------------------------------------------------------- -uint8 detector_custom_receive (uint8 *buff, uint32 length) -{ - uint8 return_state = 0; - - // 将接收到的数据写入FIFO - if(FIFO_SUCCESS != fifo_write_buffer(&detector_fifo, buff, length)) - { - return_state = 1; - } - - return return_state; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送函数 -// 参数说明 *send_data 需要发送的数据地址 -// 参数说明 send_length 需要发送的长度 -// 返回参数 uint32 剩余未发送数据长度 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint32 detector_transfer (void *send_data, uint32 send_length) -{ - return detector_transfer_callback((const uint8 *)send_data, send_length); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客求和函数 -// 参数说明 *buffer 需要校验的数据地址 -// 参数说明 length 校验长度 -// 返回参数 uint8 和值 -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -static uint8 detector_sum (uint8 *buffer, uint32 length) -{ - uint8 temp_sum = 0; - - while(length--) - { - temp_sum += *buffer++; - } - - return temp_sum; -} - - - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像发送函数 -// 参数说明 camera_type 摄像头类型 -// 参数说明 *image_addr 图像首地址 -// 参数说明 boundary_num 图像中包含边界数量 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_data_send (detector_image_type_enum camera_type, void *image_addr, uint8 boundary_num, uint16 width, uint16 height) -{ - uint32 image_size = 0; - - detector_camera_data.head = DETECTOR_SEND_HEAD; - detector_camera_data.function = DETECTOR_CAMERA_FUNCTION; - detector_camera_data.camera_type = (camera_type << 5) | ((image_addr != NULL ? 0 : 1) << 4) | boundary_num; - // 写入包长度信息,仅包含协议部分 - detector_camera_data.length = sizeof(detector_camera_struct); - detector_camera_data.image_width = width; - detector_camera_data.image_height = height; - - // 首先发送帧头、功能、摄像头类型、以及宽度高度等信息 - detector_transfer(&detector_camera_data, sizeof(detector_camera_struct)); - - // 根据摄像头类型计算图像大小 - switch(camera_type) - { - case DETECTOR_OV7725_BIN: - { - image_size = width * height / 8; - }break; - - case DETECTOR_MT9V03X: - { - image_size = width * height; - }break; - - case DETECTOR_SCC8660: - { - image_size = width * height * 2; - }break; - } - - // 发送图像数据 - if(NULL != image_addr) - { - detector_transfer(image_addr, image_size); - } - -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 图像边线绘制函数 -// 参数说明 boundary_id 边线ID -// 参数说明 dot_num 点数量 -// 参数说明 *dot_x 横坐标数据首地址 -// 参数说明 *dot_y 纵坐标数据首地址 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_dot_send (detector_camera_buffer_struct *buffer) -{ - uint8 i; - uint16 dot_bytes = 0; // 点字节数量 - wifi_spi_send_multi_struct multi_buffer; - - dot_bytes = detector_camera_dot_data.dot_num; - - if(detector_camera_dot_data.dot_type & (1 << 5)) - { - dot_bytes *= 2; - } - - // 边线发送时 WIFI SPI采用多源地址发送函数,可以极大提高发送速度 - if(DETECTOR_WIFI_SPI == detector_transfer_type) - { - multi_buffer.source[0] = (uint8 *)&detector_camera_dot_data; - multi_buffer.length[0] = sizeof(detector_camera_dot_struct); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - multi_buffer.source[i * 2 + 1] = buffer->boundary_x[i]; - multi_buffer.source[i * 2 + 2] = buffer->boundary_y[i]; - - multi_buffer.length[i * 2 + 1] = dot_bytes; - multi_buffer.length[i * 2 + 2] = dot_bytes; - } - - wifi_spi_send_buffer_multi(&multi_buffer); - } - else - { - // 首先发送帧头、功能、边界编号、坐标长度、点个数 - detector_transfer(&detector_camera_dot_data, sizeof(detector_camera_dot_struct)); - - for(i=0; i < DETECTOR_CAMERA_MAX_BOUNDARY; i++) - { - // 判断是否发送横坐标数据 - if(NULL != buffer->boundary_x[i]) - { - detector_transfer(buffer->boundary_x[i], dot_bytes); - } - - // 判断是否发送纵坐标数据 - if(NULL != buffer->boundary_y[i]) - { - // 如果没有纵坐标数据,则表示每一行只有一个边界 - // 指定了横纵坐标数据,这种方式可以实现同一行多个边界的情况,例如搜线算法能够搜索出回弯。 - detector_transfer(buffer->boundary_y[i], dot_bytes); - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 虚拟示波器发送函数 -// 参数说明 *detector_oscilloscope 示波器数据结构体 -// 返回参数 void -// 使用示例 detector_oscilloscope_send(&detector_oscilloscope_data); -//------------------------------------------------------------------------------------------------------------------- -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope) -{ - uint8 packet_size; - - // 将高四位清空 - detector_oscilloscope->channel_num &= 0x0f; - - zf_assert(DETECTOR_SET_OSCILLOSCOPE_COUNT >= detector_oscilloscope->channel_num); - - // 帧头 - detector_oscilloscope->head = DETECTOR_SEND_HEAD; - - // 写入包长度信息 - packet_size = sizeof(detector_oscilloscope_struct) - (DETECTOR_SET_OSCILLOSCOPE_COUNT - detector_oscilloscope->channel_num) * 4; - detector_oscilloscope->length = packet_size; - - // 写入功能字与通道数量 - detector_oscilloscope->channel_num |= DETECTOR_CAMERA_OSCILLOSCOPE; - - // 和校验计算 - detector_oscilloscope->check_sum = 0; - detector_oscilloscope->check_sum = detector_sum((uint8 *)&detector_oscilloscope_data, packet_size); - - // 数据在调用本函数之前,由用户将需要发送的数据写入detector_oscilloscope_data.data[] - - detector_transfer((uint8 *)detector_oscilloscope, packet_size); -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像信息配置函数 -// 参数说明 camera_type 图像类型 -// 参数说明 image_addr 图像地址 如果传递NULL参数则表示只发送边线信息到上位机 -// 参数说明 width 图像宽度 -// 参数说明 height 图像高度 -// 返回参数 void -// 使用示例 detector_camera_information_config(DETECTOR_MT9V03X, mt9v03x_image[0], MT9V03X_W, MT9V03X_H); -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height) -{ - detector_camera_dot_data.head = DETECTOR_SEND_HEAD; - detector_camera_dot_data.function = DETECTOR_CAMERA_DOT_FUNCTION; - // 写入包长度信息 - detector_camera_dot_data.length = sizeof(detector_camera_dot_struct); - - detector_camera_buffer.camera_type = camera_type; - detector_camera_buffer.image_addr = image_addr; - detector_camera_buffer.width = width; - detector_camera_buffer.height = height; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客图像边线发送配置函数 -// 参数说明 boundary_type 边界类型 -// 参数说明 dot_num 一条边界有多少个点 -// 参数说明 dot_x1 存放边线1横坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_x2 存放边线2横坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_x3 存放边线3横坐标的地址 如果传递NULL参数则表示不发送边线3 -// 参数说明 dot_y1 存放边线1纵坐标的地址 如果传递NULL参数则表示不发送边线1 -// 参数说明 dot_y2 存放边线2纵坐标的地址 如果传递NULL参数则表示不发送边线2 -// 参数说明 dot_y3 存放边线3纵坐标的地址 如果传递NULL参数则表示不发送边线3 -// 返回参数 void -// 使用示例 detector_camera_config(X_BOUNDARY, MT9V03X_H, x1_boundary, x2_boundary, x3_boundary, NULL, NULL, NULL); // 图像发送时包含三条边线,边线只有横坐标 -// 使用示例 detector_camera_config(Y_BOUNDARY, MT9V03X_W, NULL, NULL, NULL, y1_boundary, y2_boundary, y3_boundary); // 图像发送时包含三条边线,边线只有纵坐标 -// 使用示例 detector_camera_config(XY_BOUNDARY, 160, xy_x1_boundary, xy_x2_boundary, xy_x3_boundary, xy_y1_boundary, xy_y2_boundary, xy_y3_boundary); // 图像发送时包含三条边线,边线包含横纵坐标 -// 备注信息 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3) -{ - uint8 i = 0; - uint8 boundary_num = 0; - uint8 boundary_data_type = 0; - - // 检查图像发送缓冲区是否准备就绪, 调用此函数之前需要先调用detector_camera_config设置好图像信息 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_dot_data.dot_num = dot_num; - - detector_camera_dot_data.valid_flag = 0; - for(i = 0; i < 3; i++) - { - detector_camera_buffer.boundary_x[i] = NULL; - detector_camera_buffer.boundary_y[i] = NULL; - } - - switch(boundary_type) - { - case X_BOUNDARY: - { - if(NULL != dot_x1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i++] = dot_x1; - } - if(NULL != dot_x2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i++] = dot_x2; - } - if(NULL != dot_x3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i++] = dot_x3; - } - - if(255 < detector_camera_buffer.height) - { - boundary_data_type = 1; - } - }break; - - case Y_BOUNDARY: - { - if(NULL != dot_y1) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if(NULL != dot_y2) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if(NULL != dot_y3) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if(255 < detector_camera_buffer.width) - { - boundary_data_type = 1; - } - }break; - - case XY_BOUNDARY: - { - if((NULL != dot_x1) && (NULL != dot_y1)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 0; - detector_camera_buffer.boundary_x[i] = dot_x1; - detector_camera_buffer.boundary_y[i++] = dot_y1; - } - if((NULL != dot_x2) && (NULL != dot_y2)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 1; - detector_camera_buffer.boundary_x[i] = dot_x2; - detector_camera_buffer.boundary_y[i++] = dot_y2; - } - if((NULL != dot_x3) && (NULL != dot_y3)) - { - boundary_num++; - detector_camera_dot_data.valid_flag |= 1 << 2; - detector_camera_buffer.boundary_x[i] = dot_x3; - detector_camera_buffer.boundary_y[i++] = dot_y3; - } - - if((255 < detector_camera_buffer.width) || (255 < detector_camera_buffer.height)) - { - boundary_data_type = 1; - } - }break; - - case NO_BOUNDARY:break; - } - - detector_camera_dot_data.dot_type = (boundary_type << 6) | (boundary_data_type << 5) | boundary_num; -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客发送摄像头图像 -// 参数说明 void -// 返回参数 void -// 使用示例 -// 备注信息 在调用图像发送函数之前,请务必调用一次detector_camera_config函数,将对应的参数设置好 -//------------------------------------------------------------------------------------------------------------------- -void detector_camera_send (void) -{ - // 检查图像发送缓冲区是否准备就绪 - zf_assert(0 != detector_camera_buffer.camera_type); - - detector_camera_data_send(detector_camera_buffer.camera_type, detector_camera_buffer.image_addr, detector_camera_dot_data.dot_type & 0x0f, detector_camera_buffer.width, detector_camera_buffer.height); - - if(detector_camera_dot_data.dot_type & 0x0f) - { - detector_camera_dot_send(&detector_camera_buffer); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客解析接收到的数据 -// 参数说明 void -// 返回参数 void -// 使用示例 函数只需要放到周期运行的PIT中断或者主循环即可 -//------------------------------------------------------------------------------------------------------------------- -void detector_data_analysis (void) -{ - uint8 temp_sum; - uint32 read_length; - detector_parameter_struct *receive_packet; - - // 这里使用uint32进行定义,目的是为了保证数组四字节对齐 - uint32 temp_buffer[DETECTOR_BUFFER_SIZE / 4]; - - // 尝试读取数据, 如果不是自定义的传输方式则从接收回调中读取数据 - if(DETECTOR_CUSTOM != detector_transfer_type) - { - read_length = detector_receive_callback((uint8 *)temp_buffer, DETECTOR_BUFFER_SIZE); - if(read_length) - { - // 将读取到的数据写入FIFO - fifo_write_buffer(&detector_fifo, (uint8 *)temp_buffer, read_length); - } - } - - while(sizeof(detector_parameter_struct) <= fifo_used(&detector_fifo)) - { - read_length = sizeof(detector_parameter_struct); - fifo_read_buffer(&detector_fifo, (uint8 *)temp_buffer, &read_length, FIFO_READ_ONLY); - - if(DETECTOR_RECEIVE_HEAD != ((uint8 *)temp_buffer)[0]) - { - // 没有帧头则从FIFO中去掉第一个数据 - read_length = 1; - } - else - { - // 找到帧头 - receive_packet = (detector_parameter_struct *)temp_buffer; - temp_sum = receive_packet->check_sum; - receive_packet->check_sum = 0; - if(temp_sum == detector_sum((uint8 *)temp_buffer, sizeof(detector_parameter_struct))) - { - // 和校验成功保存数据 - detector_parameter[receive_packet->channel - 1] = receive_packet->data; - } - else - { - read_length = 1; - } - } - - // 丢弃无需使用的数据 - fifo_read_buffer(&detector_fifo, NULL, &read_length, FIFO_READ_AND_CLEAN); - } -} - -//------------------------------------------------------------------------------------------------------------------- -// 函数简介 滴答客 初始化 -// 参数说明 transfer_type 选择使用哪种方式传输数据 -// 返回参数 void -// 使用示例 -//------------------------------------------------------------------------------------------------------------------- -void detector_init (detector_transfer_type_enum transfer_type) -{ - detector_transfer_type = transfer_type; - - fifo_init(&detector_fifo, FIFO_DATA_8BIT, detector_buffer, DETECTOR_BUFFER_SIZE); - - switch(detector_transfer_type) - { - case DETECTOR_DEBUG_UART: - { - detector_transfer_callback = debug_send_buffer; - detector_receive_callback = debug_read_ring_buffer; - }break; - - case DETECTOR_WIRELESS_UART: - { - detector_transfer_callback = wireless_uart_send_buffer; - detector_receive_callback = wireless_uart_read_buffer; - }break; - - case DETECTOR_CH9141: - { - detector_transfer_callback = bluetooth_ch9141_send_buffer; - detector_receive_callback = bluetooth_ch9141_read_buffer; - }break; - - case DETECTOR_WIFI_UART: - { - detector_transfer_callback = wifi_uart_send_buffer; - detector_receive_callback = wifi_uart_read_buffer; - }break; - - case DETECTOR_WIFI_SPI: - { - detector_transfer_callback = wifi_spi_send_buffer; - detector_receive_callback = wifi_spi_read_buffer; - }break; - - case DETECTOR_CUSTOM: - { - // 根据自己的需求 自行实现detector_custom_write_byte函数,完成数据的传输 - detector_transfer_callback = detector_custom_transfer; - - // 无需设置接收回调 - - // 在合适的位置调用detector_custom_receive 或者 detector_custom_receive_byte函数即可实现数据接收 - // detector_custom_receive 或者 detector_custom_receive_byte函数 只需调用一个函数即可,根据自己的需求是按字节接收数据还是按照数据接收数据 - // 接收到的数据会被写入detector_fifo中, 以备解析函数使用 - //detector_receive_callback = detector_custom_receive; - - }break; - } -} diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_detector.h b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_detector.h deleted file mode 100644 index ee2ea7e..0000000 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_detector.h +++ /dev/null @@ -1,173 +0,0 @@ -/********************************************************************************************************************* -* 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_detector -* 公司名称 成都逐飞科技有限公司 -* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明 -* 开发环境 ADS v1.9.4 -* 适用平台 TC264D -* 店铺链接 https://seekfree.taobao.com/ -* -* 修改记录 -* 日期 作者 备注 -* 2023-05-27 pudding first version -********************************************************************************************************************/ - -#ifndef _zf_device_detector_h_ -#define _zf_device_detector_h_ - -#include "zf_common_typedef.h" -#include "zf_common_debug.h" - -// 定义接收FIFO大小 -#define DETECTOR_BUFFER_SIZE ( 0x40 ) - -// 定义示波器的最大通道数量 -#define DETECTOR_SET_OSCILLOSCOPE_COUNT ( 0x08 ) - -// 定义参数调试的最大通道数量 -#define DETECTOR_SET_PARAMETR_COUNT ( 0x08 ) - -// 定义图像边线最大数量 -#define DETECTOR_CAMERA_MAX_BOUNDARY ( 0x08 ) - -// 单片机往上位机发送的帧头 -#define DETECTOR_SEND_HEAD ( 0xAA ) - -// 摄像头类 -#define DETECTOR_CAMERA_FUNCTION ( 0x02 ) -#define DETECTOR_CAMERA_DOT_FUNCTION ( 0x03 ) -#define DETECTOR_CAMERA_OSCILLOSCOPE ( 0x10 ) - -// 上位机往单片机发送的帧头 -#define DETECTOR_RECEIVE_HEAD ( 0x55 ) - -// 参数设置类 -#define DETECTOR_RECEIVE_SET_PARAMETER ( 0x20 ) - - -// 数据发送设备枚举 -typedef enum -{ - DETECTOR_DEBUG_UART, // 调试串口 使用的串口由DEBUG_UART_INDEX宏定义指定 - DETECTOR_WIRELESS_UART, // 无线转串口 - DETECTOR_CH9141, // 9141蓝牙 - DETECTOR_WIFI_UART, // WIFI转串口 - DETECTOR_WIFI_SPI, // 高速WIFI SPI - DETECTOR_CUSTOM, // 自定义通讯方式 需要自行detector_custom_write_byte函数中实现数据发送 -}detector_transfer_type_enum; - - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - DETECTOR_OV7725_BIN = 1, - DETECTOR_MT9V03X, - DETECTOR_SCC8660, - - // 按照图像类型定义 - DETECTOR_BINARY = 1, - DETECTOR_GRAY, - DETECTOR_RGB565, -}detector_image_type_enum; - -// 摄像头类型枚举 -typedef enum -{ - // 按照摄像头型号定义 - X_BOUNDARY, // 发送的图像中边界信息只包含X,也就是只有横坐标信息,纵坐标根据图像高度得到 - Y_BOUNDARY, // 发送的图像中边界信息只包含Y,也就是只有纵坐标信息,横坐标根据图像宽度得到,通常很少有这样的需求 - XY_BOUNDARY, // 发送的图像中边界信息包含X与Y,这样可以指定点在任意位置,就可以方便显示出回弯的效果 - NO_BOUNDARY, // 发送的图像中没有边线信息 -}detector_boundary_type_enum; - -typedef struct -{ - uint8 head; // 帧头 - uint8 channel_num; // 高四位为功能字 低四位为通道数量 - uint8 check_sum; // 和校验 - uint8 length; // 包长度 - float data[DETECTOR_SET_OSCILLOSCOPE_COUNT]; // 通道数据 -}detector_oscilloscope_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 camera_type; // 低四位表示边界数量 第四位表示是否有图像数据 例如0x13:其中3表示一副图像有三条边界(通常是左边界、中线、右边界)、1表示没有图像数据 - uint8 length; // 包长度(仅包含协议部分) - uint16 image_width; // 图像宽度 - uint16 image_height; // 图像高度 -}detector_camera_struct; - - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 dot_type; // 点类型 BIT5:1:坐标是16位的 0:坐标是8位的 BIT7-BIT6:0:只有X坐标 1:只有Y坐标 2:X和Y坐标都有 BIT3-BIT0:边界数量 - uint8 length; // 包长度(仅包含协议部分) - uint16 dot_num; // 画点数量 - uint8 valid_flag; // 通道标识 - uint8 reserve; // 保留 -}detector_camera_dot_struct; - -typedef struct -{ - void *image_addr; // 摄像头地址 - uint16 width; // 图像宽度 - uint16 height; // 图像高度 - detector_image_type_enum camera_type; // 摄像头类型 - void *boundary_x[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界横坐标数组地址 - void *boundary_y[DETECTOR_CAMERA_MAX_BOUNDARY]; // 边界纵坐标数组地址 -}detector_camera_buffer_struct; - -typedef struct -{ - uint8 head; // 帧头 - uint8 function; // 功能字 - uint8 channel; // 通道 - uint8 check_sum; // 和校验 - float data; // 数据 -}detector_parameter_struct; - - -extern detector_oscilloscope_struct detector_oscilloscope_data; // 虚拟示波器数据 -extern float detector_parameter[DETECTOR_SET_PARAMETR_COUNT]; // 保存接收到的参数 - - -void detector_oscilloscope_send (detector_oscilloscope_struct *detector_oscilloscope); - -void detector_camera_information_config (detector_image_type_enum camera_type, void *image_addr, uint16 width, uint16 height); -void detector_camera_boundary_config (detector_boundary_type_enum boundary_type, uint16 dot_num, void *dot_x1, void *dot_x2, void *dot_x3, void *dot_y1, void *dot_y2, void *dot_y3); -void detector_camera_send (void); - -void detector_data_analysis (void); -void detector_init (detector_transfer_type_enum transfer_type); - - - -#endif - diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_gps_tau1201.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_gps_tau1201.c index 6ab1ea7..da46a99 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_gps_tau1201.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_gps_tau1201.c @@ -58,7 +58,7 @@ uint8 gps_tau1201_flag = 0; gps_info_struct gps_tau1201; // GPS解析之后的数据 static uint8 gps_tau1201_state = 0; // 1:GPS初始化完成 -static fifo_struct gps_tau1201_receiver_fifo; // +static fifo_obj_struct gps_tau1201_receiver_fifo; // static uint8 gps_tau1201_receiver_buffer[GPS_TAU1201_BUFFER_SIZE]; // 数据存放数组 gps_state_enum gps_gga_state = GPS_STATE_RECEIVING; // gga 语句状态 diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_ov7725.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_ov7725.c index 28f8a7d..12f6095 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_ov7725.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_ov7725.c @@ -501,11 +501,11 @@ uint8 ov7725_init (void) // 获取所有参数 if(ov7725_get_config(ov7725_get_confing_buffer)) { - uart_rx_interrupt(OV7725_COF_UART, 0); - system_delay_ms(200); - set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, ov7725_uart_handler); // 设置连接摄像头类型 - if(ov7725_iic_init()) - { + uart_rx_interrupt(OV7725_COF_UART, 0); + system_delay_ms(200); + set_camera_type(CAMERA_BIN_IIC, ov7725_vsync_handler, ov7725_dma_handler, NULL); // 设置连接摄像头类型 + if(ov7725_iic_init()) + { zf_log(0, "OV7725 IIC error."); set_camera_type(NO_CAMERE, NULL, NULL, NULL); return_state = 1; diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_spi.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_spi.c index d04df4f..78a6d68 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_spi.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_spi.c @@ -65,7 +65,7 @@ #define WAIT_TIME_OUT (10000) // 单指令等待时间 单位:ms -#define WIFI_SPI_WRITE_MAX 4092 // 定义一次SPI通讯最大发送的数据长度 +#define WIFI_SPI_WRITE_MAX 128 // 定义一次SPI通讯最大发送的数据长度 #define WIFI_SPI_WRITE_REQUEST 0x01 #define WIFI_SPI_CHECK_STATE 0x02 @@ -80,7 +80,7 @@ volatile wifi_spi_buffer_state_enum wifi_buffer_state; volatile wifi_spi_transmit_state_enum wifi_transmit_state; -static fifo_struct wifi_spi_fifo; +static fifo_obj_struct wifi_spi_fifo; static uint8 wifi_spi_buffer[WIFI_SPI_BUFFER_SIZE]; // 数据存放数组 vuint8 wifi_spi_ack_flag = 0; // 0:模块未应答 1:模块已应答 @@ -88,7 +88,7 @@ uint8 wifi_spi_init_flag; // 0 vuint8 wifi_spi_packet_num; // 发送的数据包ID vuint32 wifi_spi_send_remain_length; // 剩余的发送长度 -uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + wifi_spi_information_struct wifi_spi_information; //------------------------------------------------------------------------------------------------------------------- @@ -145,7 +145,7 @@ static wifi_spi_buffer_state_enum wifi_spi_read_state(uint16 *length) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据发送完成 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -165,7 +165,26 @@ static void wifi_spi_send_done(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 数据接收完成 -// 参数说明 void +// 参数说明 void +// @return void +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +static void wifi_spi_receive_start(void) +{ + wifi_spi_buffer_struct head; + + head.cmd = WIFI_SPI_READ_DATA; + head.addr = WIFI_SPI_WRITE_ADDR; + head.dummy = 0x00; + + gpio_set_level(WIFI_SPI_CS_PIN, 0); + spi_write_8bit_array(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, 3); + wifi_transmit_state = TRANSMIT_READ; +} + +//------------------------------------------------------------------------------------------------------------------- +// 函数简介 数据接收完成 +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- @@ -173,6 +192,8 @@ static void wifi_spi_receive_done(void) { wifi_spi_buffer_struct head; + gpio_set_level(WIFI_SPI_CS_PIN, 1); + head.cmd = WIFI_SPI_READ_END; head.addr = WIFI_SPI_WRITE_ADDR; head.dummy = 0x00; @@ -242,18 +263,7 @@ static void wifi_spi_send_data_multi(wifi_spi_send_multi_struct *multi_buffer) //------------------------------------------------------------------------------------------------------------------- static void wifi_spi_receive_data(uint8 *buff, uint16 length) { - wifi_spi_buffer_struct head; - - head.cmd = WIFI_SPI_READ_DATA; - head.addr = WIFI_SPI_WRITE_ADDR; - head.dummy = 0x00; - - wifi_transmit_state = TRANSMIT_READ; - gpio_set_level(WIFI_SPI_CS_PIN, 0); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)&head.cmd, &head.cmd, 3); - spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)buff, buff, length); - gpio_set_level(WIFI_SPI_CS_PIN, 1); - wifi_spi_receive_done(); + spi_read_8bit_array(WIFI_SPI_INDEX, buff, length); } //------------------------------------------------------------------------------------------------------------------- @@ -309,22 +319,38 @@ static void wifi_spi_send_command(const char *str) //------------------------------------------------------------------------------------------------------------------- // 函数简介 检查模块状态并读取模块发送的数据 -// 参数说明 void +// 参数说明 void // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- void wifi_spi_check_state_read_buffer(void) { uint16 wifi_spi_receive_length; // 本次接收到的数据数量 - + uint8 wifi_spi_receive_buffer[WIFI_SPI_WRITE_MAX]; + // 查询WIFI模块的状态 wifi_buffer_state = wifi_spi_read_state(&wifi_spi_receive_length); - + // 如果需要读取WIFI模块数据,则保存需要读取的长度 if(BUFFER_READ == wifi_buffer_state) { - wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); - fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_start(); + do + { + if(wifi_spi_receive_length > WIFI_SPI_WRITE_MAX) + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, WIFI_SPI_WRITE_MAX); // 存入 FIFO + wifi_spi_receive_length = wifi_spi_receive_length - WIFI_SPI_WRITE_MAX; + } + else + { + wifi_spi_receive_data((uint8 *)wifi_spi_receive_buffer, wifi_spi_receive_length); + fifo_write_buffer(&wifi_spi_fifo, wifi_spi_receive_buffer, wifi_spi_receive_length); // 存入 FIFO + wifi_spi_receive_length = 0; + } + }while(wifi_spi_receive_length > 0); + wifi_spi_receive_done(); } else if(BUFFER_IDLE == wifi_buffer_state) { @@ -335,7 +361,7 @@ void wifi_spi_check_state_read_buffer(void) //------------------------------------------------------------------------------------------------------------------- // 函数简介 发送数据到模块 -// 参数说明 *buff 需要发送的数据首地址 +// 参数说明 *buff 需要发送的数据首地址 // 参数说明 length 需要发送的长度 // @return uint32 剩余未发送长度 // Sample usage: @@ -787,7 +813,7 @@ static uint8 wifi_spi_set_transfer_model (char *model) // 参数说明 state 0:无 Wi-Fi 模式,并且关闭 Wi-Fi RF----1: Station 模式----2: SoftAP 模式----3: SoftAP+Station 模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_set_model("1"); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_set_model (wifi_spi_mode_enum mode) { @@ -836,7 +862,7 @@ uint8 wifi_spi_close_sleep_model (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnected_wifi(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnected_wifi (void) { @@ -855,7 +881,7 @@ uint8 wifi_spi_disconnected_wifi (void) // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_entry_serianet(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_entry_serianet (void) { @@ -874,7 +900,7 @@ uint8 wifi_spi_entry_serianet (void) // 参数说明 model 0:关闭透传模式 其他:开启透传模式 // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_exit_serianet(1); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_exit_serianet (void) { @@ -1042,7 +1068,7 @@ uint8 wifi_spi_connect_udp_client (char *ip, char *port, char *local_port, wifi_ // 参数说明 void // 返回参数 uint8 0:成功 1:失败 // 使用示例 wifi_spi_disconnect_link(); -// 备注信息 +// 备注信息 //-------------------------------------------------------------------------------------------------- uint8 wifi_spi_disconnect_link (void) { @@ -1191,7 +1217,7 @@ uint32 wifi_spi_send_buffer (const uint8 *buff, uint32 len) // 函数简介 WiFi模块 发送缓冲区函数(多个源地址) // 参数说明 *multi_buffer 多个源地址以及每个源地址需要发送的长度 // 返回参数 uint32 剩余未发送数据长度 -// 使用示例 +// 使用示例 // 备注信息 需要发送多个数组时,采用此函数可以极大的降低通讯时间,发送数据总长度不能超过4092 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_send_buffer_multi (wifi_spi_send_multi_struct *multi_buffer) @@ -1278,7 +1304,7 @@ uint32 wifi_spi_send_string (const char *str) // 参数说明 len 数组长度,可直接填写或者使用sizeof求得 // 返回参数 uint32 返回实际接收到的数据长度 // 使用示例 uint8 test_buffer[256]; wifi_spi_read_buffer(&test_buffer[0], sizeof(test_buffer)); -// 备注信息 +// 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) { @@ -1289,7 +1315,7 @@ uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 len) //-------------------------------------------------------------------------------------------------- // 函数简介 wifi spi handshake中断回调函数 // 参数说明 void -// 返回参数 void +// 返回参数 void // 备注信息 内部调用 //-------------------------------------------------------------------------------------------------- void wifi_spi_callback (void) diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_uart.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_uart.c index 2f66c33..312dab7 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_uart.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wifi_uart.c @@ -61,7 +61,7 @@ wifi_uart_information_struct wifi_uart_information; // 模块自身参数 -static fifo_struct wifi_uart_fifo; +static fifo_obj_struct wifi_uart_fifo; static uint8 wifi_uart_buffer[WIFI_UART_BUFFER_SIZE]; // 数据存放数组 static uint8 wifi_uart_data; diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wireless_uart.c b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wireless_uart.c index 5535770..eac2867 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wireless_uart.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_device/zf_device_wireless_uart.c @@ -53,7 +53,7 @@ #include "zf_device_type.h" #include "zf_device_wireless_uart.h" -static fifo_struct wireless_uart_fifo; +static fifo_obj_struct wireless_uart_fifo; static uint8 wireless_uart_buffer[WIRELESS_UART_BUFFER_SIZE]; static uint8 wireless_uart_data = 0; diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_delay.h b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_delay.h index 88578e5..e8d82ef 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_delay.h +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_delay.h @@ -31,6 +31,7 @@ * 修改记录 * 日期 作者 备注 * 2022-09-15 pudding first version +* 2023-11-28 pudding 新增初始化函数 ********************************************************************************************************************/ #ifndef _zf_driver_delay_h_ diff --git a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_dma.c b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_dma.c index 04b0f26..f72f1d6 100644 --- a/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_dma.c +++ b/Seekfree_TC264_Opensource_Library/libraries/zf_driver/zf_driver_dma.c @@ -85,7 +85,7 @@ uint8 dma_init (IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_ uint8 list_num, i; uint16 single_channel_dma_count; - zf_assert(!(dma_count%8)); // 传输次数必须为8的倍数 + zf_assert(!(dma_count % 8)); // 传输次数必须为8的倍数 list_num = 1; 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 b7c5430..cd19782 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 @@ -402,7 +402,6 @@ void uart_rx_interrupt (uart_index_enum uart_n, uint32 status) { IfxSrc_disable(src); } - } //-------------------------------------------------------------------------------------------------------------------