Files
32343 843447835d Initial commit: TC264 smart car project with IPS200 menu system
- IPS200 display menu with real-time status and parameter settings
- Camera image processing and line tracking
- IMU attitude solution and PID control
- WiFi SPI oscilloscope data transmission
2026-05-10 21:38:49 +08:00

990 lines
37 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*********************************************************************************************************************
* TC264 Opensourec Library 即(TC264 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是 TC264 开源库的一部分
*
* TC264 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL(GNU General Public License,即 GNU通用公共许可证)的条款
* 即 GPL 的第3版(即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_ips200pro
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 ADS v1.10.2
* 适用平台 TC264D
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2025-05-15 seekfree first version
********************************************************************************************************************/
/********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* // SPI 串口 SPI 两寸屏 硬件引脚
* SCL 查看 zf_device_ips200pro.h 中 IPS200PRO_SCL_PIN_SPI 宏定义
* SDA 查看 zf_device_ips200pro.h 中 IPS200PRO_SDA_PIN_SPI 宏定义
* RST 查看 zf_device_ips200pro.h 中 IPS200PRO_RST_PIN_SPI 宏定义
* DC 查看 zf_device_ips200pro.h 中 IPS200PRO_DC_PIN_SPI 宏定义
* CS 查看 zf_device_ips200pro.h 中 IPS200PRO_CS_PIN_SPI 宏定义
* BLk 查看 zf_device_ips200pro.h 中 IPS200PRO_BLk_PIN_SPI 宏定义
* VCC 3.3V电源
* GND 电源地
* 最大分辨率 320 * 240
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_debug.h"
#include "zf_common_function.h"
#include "zf_driver_delay.h"
#include "zf_driver_soft_spi.h"
#include "zf_driver_spi.h"
#include "zf_device_type.h"
#include "zf_device_ips200pro.h"
#define IPS200PRO_SPI_LENGTH ( 4096 ) // 每次SPI通讯最大长度 不可修改
// 不可修改
#define MAX_ID_PAGE ( 30 )
#define MAX_ID_LABEL ( 50 )
#define MAX_ID_TABLE ( 20 )
#define MAX_ID_METER ( 10 )
#define MAX_ID_CLOCK ( 1 )
#define MAX_ID_PROGRESS_BAR ( 20 )
#define MAX_ID_CALENDAR ( 1 )
#define MAX_ID_WAVEFORM ( 5 )
#define MAX_ID_WAVEFORM_LINE ( 5 )
#define MAX_ID_IMAGE ( 5 )
#define MAX_ID_IMAGE_LINE ( 10 )
#define MAX_ID_IMAGE_RECTANGLE ( 5 )
#define MAX_ID_CONTAINER ( 20 )
ips200pro_information_struct ips200pro_information;
ips200pro_time_struct ips200pro_time;
static char ips200pro_printf_buffer[51];
static uint8 ips200pro_lebel_num = 0;
static uint8 ips200pro_table_num = 0;
static uint8 ips200pro_meter_num = 0;
static uint8 ips200pro_clock_num = 0;
static uint8 ips200pro_progress_bar_num = 0;
static uint8 ips200pro_waveform_num = 0;
static uint8 ips200pro_image_num = 0;
static uint8 ips200pro_container_num = 0;
static uint8 ips200pro_page_num = 0;
// 系统参数的子命令与屏幕组件的子命令
typedef enum
{
// 可读可写的参数
IPS200PRO_SYSTEM_DATE = 0x01,// 系统日期
IPS200PRO_SYSTEM_TIME, // 系统时间
IPS200PRO_SYSTEM_PARENT, // 父对象
IPS200PRO_SYSTEM_CODED_FORMAT, // 编码格式
IPS200PRO_SYSTEM_BACKLIGHT, // 背光亮度
IPS200PRO_SYSTEM_DIRECTION, // 屏幕显示方向
IPS200PRO_SYSTEM_CRC_STATE, // CRC使能状态
IPS200PRO_SYSTEM_FONT_SIZE, // 全局字体
SCREEN_SYSTEM_OPTIMIZE, // 优化 目前仅针对图像进行优化(默认优化开启)
IPS200PRO_SYSTEM_THEME, // 系统主题
IPS200PRO_SYSTEM_SET_MAX, // 占位使用
// 仅可读的参数
IPS200PRO_SYSTEM_INFORMATION = 0x10, // 屏幕ID编号、分辨率、固件版本
IPS200PRO_SYSTEM_FREE_STACK, // 系统空闲栈大小
IPS200PRO_SYSTEM_GET_MAX, // 占位使用
// 通用操作命令
IPS200PRO_COMMON_CREATE = 0x01, // 组件创建
IPS200PRO_COMMON_DELETE, // 组件删除
IPS200PRO_COMMON_FONT_SIZE, // 组件字体大小
IPS200PRO_COMMON_COLOR, // 组件颜色
IPS200PRO_COMMON_VALUE, // 组件数值 不同组件数据类型不同
IPS200PRO_COMMON_POSITION, // 组件位置
IPS200PRO_COMMON_HIDDEN, // 组件隐藏
IPS200PRO_COMMON_MAX, // 占位
// PAGE组件专用命令
IPS200PRO_PAGE_SWITCH = 0x10, // 切换页面
IPS200PRO_PAGE_TITLE, // 设置页面标题显示位置与宽度
IPS200PRO_PAGE_MAX,
// LABEL组件专用命令
IPS200PRO_LABEL_LONG_MODE = 0x10, // 长文本模式
IPS200PRO_LABEL_MAX,
// TABLE组件专用命令
IPS200PRO_TABLE_COL_WIDTH = 0x10, // 表格列宽度设置 行高由屏幕自动调整,无法设置
IPS200PRO_TABLE_SELECT, // 表格中单元格选中
IPS200PRO_TABLE_MAX,
// WAVEFORM组件专用命令
IPS200PRO_WAVEFORM_LINE_STATE = 0x10, // 隐藏指定线条
IPS200PRO_WAVEFORM_LINE_TYPE, // 设置组件中线条的类型
IPS200PRO_WAVEFORM_CLEAR, // 将所有数据清空
IPS200PRO_WAVEFORM_MAX,
// IMAGE组件专用命令
IPS200PRO_IMAGE_DRAW_LINE = 0x10, // 图像画线
IPS200PRO_IMAGE_DRAW_RECTANGLE, // 图像画框
IPS200PRO_IMAGE_MAX,
}ips200pro_command2_enum;
// 这里使用宏定义的方式,目的是为了避免使用匿名结构体,导致部分IDE无法在线调试的时候查看匿名结构体的数据
#define IPS200PRO_HEADER \
uint8 command1; /* 命令1 */ \
uint8 command2; /* 命令2 */ \
uint8 check_crc8; /* CRC校验、默认未启用 */ \
uint8 widgets_id; /* ID编号 */ \
uint32 length /* 数据包长度 */ \
typedef struct
{
IPS200PRO_HEADER;
}ips200pro_header_struct;
// 数据拆分联合体
typedef union
{
int8 int8_data[2]; // 有符号字节数据
uint8 uint8_data[2]; // 无符号字节数据
int16 int16_data; // 有符号半字数据
uint16 uint16_data; // 无符号半字数据
}data_split_union;
// 通用结构体
#define IPS200PRO_COMMON_STRUCT(name, num) \
struct common_packet\
{\
IPS200PRO_HEADER; \
data_split_union data[num]; \
}name;
#define ips200pro_write_8bit_data_spi_array(data, len) (spi_write_8bit_array(IPS200PRO_SPI_INDEX, (data), (len)))
#define ips200pro_transfer_8bit_data_spi_array(tx_data, rx_data, len) (spi_transfer_8bit(IPS200PRO_SPI_INDEX, (tx_data), (rx_data), (len)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 屏幕等待函数
// 参数说明 wait_time 等待时间
// 返回参数 uint8 1:超时退出 0:未超时
// 使用示例
// 备注信息 内部使用,用户无需关心
//-------------------------------------------------------------------------------------------------------------------
static uint8 ips200pro_wait_idle (uint32 wait_time)
{
wait_time = wait_time * 100;
while(0 == gpio_get_level(IPS200PRO_INT_PIN) && (0 != wait_time))
{
func_soft_delay(1000);
wait_time--;
}
return (!wait_time);
}
#if(1 == IPS200PRO_CRC_ENABLE)
static uint8 ips200pro_calculate_crc8(uint8 *data, uint32 length)
{
uint8 i, crc = 0;
while(length--)
{
crc ^= *data++;
for (i = 0; i < 8; i++)
{
crc = (crc & 0x80) ? ((crc << 1) ^ 0x07) : (crc <<= 1);
}
}
return crc;
}
#endif
uint8 ips200pro_send_buffer(const void *buffer, uint32 length, uint32 time_out, uint8 end_flag)
{
uint8 return_state = 1;
if( ((0 == time_out) || (0 == ips200pro_wait_idle(time_out))) // 等待未超时
&& (IPS200PRO_SPI_LENGTH >= length) // 数据量未超过限制
&& (NULL != buffer)) // 指针不为空
{
gpio_low(IPS200PRO_CS_PIN);
ips200pro_write_8bit_data_spi_array((const uint8 *)buffer, length);
if(1 == end_flag)
{
gpio_high(IPS200PRO_CS_PIN);
}
return_state = 0;
}
return return_state;
}
uint8 ips200pro_receive_buffer(void *buffer, uint32 length, uint32 time_out)
{
uint8 return_state = 1;
if( ((0 == time_out) || (0 == ips200pro_wait_idle(time_out))) // 等待未超时
&& (IPS200PRO_SPI_LENGTH >= length) // 数据量未超过限制
&& (NULL != buffer)) // 指针不为空
{
gpio_low(IPS200PRO_CS_PIN);
ips200pro_transfer_8bit_data_spi_array((const uint8 *)buffer, (uint8 *)buffer, length);
gpio_high(IPS200PRO_CS_PIN);
return_state = 0;
}
return return_state;
}
uint8 ips200pro_write_packet(ips200pro_command1_enum command1, ips200pro_command2_enum command2, uint8 widgets_id, ips200pro_header_struct *temp, uint32 length, const void *buffer, uint32 buffer_length)
{
uint8 return_state = 1;
temp->command1 = command1;
temp->command2 = command2;
temp->widgets_id = widgets_id;
temp->length = length + buffer_length;
#if(1 == IPS200PRO_CRC_ENABLE)
temp->check_crc8 = 0;
temp->check_crc8 = ips200pro_calculate_crc8((uint8 *)temp, length);
#endif
return_state = ips200pro_send_buffer(temp, length, IPS200PRO_WAIT_TIME, NULL == buffer);
if((0 == return_state) && (NULL != buffer) && (0 != buffer_length))
{
return_state = ips200pro_send_buffer(buffer, buffer_length, 0, 1);
}
else
{
gpio_high(IPS200PRO_CS_PIN);
}
return return_state;
}
uint8 ips200pro_read_parameter(ips200pro_command2_enum command2, ips200pro_header_struct *temp, uint8 length)
{
uint8 return_state;
temp->command1 = IPS200PRO_PARAMETER_GET;
temp->command2 = command2;
temp->length = length;
// 发送命令
return_state = ips200pro_send_buffer(temp, length, IPS200PRO_WAIT_TIME, 1);
// 读取数据
temp->command1 = 0x00;
return_state = ips200pro_receive_buffer(temp, length, IPS200PRO_WAIT_TIME);
//*parameter = temp.data[0].uint8_data[0];
return return_state;
}
uint8 ips200pro_set_date(uint16 year, uint8 month, uint8 day)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = year;
temp.data[1].uint8_data[0] = month;
temp.data[1].uint8_data[1] = day;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_DATE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_time(uint8 hour, uint8 minute, uint8 second)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint8_data[0] = hour;
temp.data[0].uint8_data[1] = minute;
temp.data[1].uint8_data[0] = second;
temp.data[1].uint8_data[1] = 0;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_TIME, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_parent(uint16 child_id, uint16 parent_id)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint8_data[0] = (uint8)child_id;
temp.data[0].uint8_data[1] = child_id >> 8;
temp.data[1].uint8_data[0] = (uint8)parent_id;
temp.data[1].uint8_data[1] = parent_id >> 8;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_PARENT, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_format(ips200pro_format_enum format)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = format;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_CODED_FORMAT, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_backlight(uint8 backlight)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = backlight;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_BACKLIGHT, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_direction(ips200pro_display_direction_enum dir)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = dir;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_DIRECTION, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_crc_state(uint8 crc_state)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = crc_state;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_CRC_STATE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_default_font(ips200pro_font_size_enum font)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = font;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, IPS200PRO_SYSTEM_FONT_SIZE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_optimize(uint8 state)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint8_data[0] = state;
return_state = ips200pro_write_packet(IPS200PRO_PARAMETER_SET, SCREEN_SYSTEM_OPTIMIZE, 0, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_get_date(ips200pro_time_struct *time)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_DATE, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
memcpy(&time->year, &(temp.data[0]), 4);
}
return return_state;
}
uint8 ips200pro_get_time(ips200pro_time_struct *time)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_TIME, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
memcpy(&time->hour, &(temp.data[0]), 4);
}
return return_state;
}
uint8 ips200pro_get_information(ips200pro_information_struct *information)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 4);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_INFORMATION, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
information->version_major = temp.widgets_id; // 主版本
memcpy(&information->id, &(temp.data[0]), 8);
}
return return_state;
}
uint8 ips200pro_get_free_stack_size(uint32 *stack_size)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
return_state = ips200pro_read_parameter(IPS200PRO_SYSTEM_FREE_STACK, (ips200pro_header_struct *)&temp, sizeof(temp));
if(0 == return_state)
{
*stack_size = *((uint32 *)&temp.data[0]);
}
return return_state;
}
uint8 ips200pro_create_widgets(uint16 widgets_id, int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 4);
temp.data[0].int16_data = x;
temp.data[1].int16_data = y;
temp.data[2].uint16_data = width;
temp.data[3].uint16_data = height;
if(ips200pro_page_num || (IPS200PRO_WIDGETS_PAGE == (widgets_id >> 8)))
{
// 只有在页面已经创建后,才允许创建其他组件
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_CREATE, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
}
return return_state;
}
uint8 ips200pro_set_font(uint16 widgets_id, ips200pro_font_size_enum font_size)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = font_size;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_FONT_SIZE, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_color(uint16 widgets_id, ips200pro_widgets_color_type_enum color_type, uint16 color)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = color_type;
temp.data[1].uint16_data = color;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_COLOR, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_position(uint16 widgets_id, int16 x, int16 y)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].int16_data = x;
temp.data[1].int16_data = y;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_POSITION, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_set_hidden(uint16 widgets_id, uint8 state)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = state;
return_state = ips200pro_write_packet(widgets_id >> 8, IPS200PRO_COMMON_HIDDEN, (uint8)widgets_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_page_create(char *str)
{
uint8 return_state = 1;
if(MAX_ID_PAGE > ips200pro_page_num)
{
return_state = ips200pro_create_widgets(++ips200pro_page_num | (IPS200PRO_WIDGETS_PAGE << 8), 0, 0, 0, 0);
if(1 == return_state)
{
ips200pro_page_num--;
}
else if(NULL != str)
{
return_state = ips200pro_page_set_title_name(ips200pro_page_num, str);
}
}
return return_state == 1 ? 0 : (ips200pro_page_num | (IPS200PRO_WIDGETS_PAGE << 8));
}
uint8 ips200pro_page_switch(uint16 page_id, ips200pro_page_animations_enum anim_en)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = anim_en;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_PAGE, IPS200PRO_PAGE_SWITCH, (uint8)page_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_page_hidden(uint16 page_id, uint8 state)
{
uint8 return_state;
if(0 == page_id)
{
page_id = 0 | (IPS200PRO_WIDGETS_PAGE << 8);
}
return_state = ips200pro_set_hidden(page_id, state);
return return_state;
}
uint8 ips200pro_page_set_title_name(uint16 page_id, char *str)
{
uint8 return_state;
ips200pro_header_struct temp;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_PAGE, IPS200PRO_COMMON_VALUE, (uint8)page_id, (ips200pro_header_struct *)&temp, sizeof(temp), str, strlen(str));
return return_state;
}
uint8 ips200pro_page_set_title_position_width(ips200pro_title_position_enum title_position, uint8 title_width)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = title_position;
temp.data[1].uint16_data = title_width;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_PAGE, IPS200PRO_PAGE_TITLE, 1, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_label_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
if(MAX_ID_LABEL > ips200pro_lebel_num)
{
return_state = ips200pro_create_widgets(++ips200pro_lebel_num | (IPS200PRO_WIDGETS_LABEL << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_lebel_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_lebel_num | (IPS200PRO_WIDGETS_LABEL << 8));
}
uint8 ips200pro_label_printf(uint16 label_id, const char *format, ...)
{
int32 str_length;
va_list arg;
va_start(arg, format);
uint8 return_state = 1;
ips200pro_header_struct temp;
str_length = vsnprintf(ips200pro_printf_buffer, sizeof(ips200pro_printf_buffer) - 1, format, arg);
if(0 <= str_length)
{
temp.length = (uint32)str_length;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_LABEL, IPS200PRO_COMMON_VALUE, (uint8)label_id, (ips200pro_header_struct *)&temp, sizeof(temp), ips200pro_printf_buffer, temp.length);
}
va_end(arg);
return return_state;
}
uint8 ips200pro_label_show_string(uint16 label_id, const char *str)
{
uint8 return_state;
ips200pro_header_struct temp;
temp.length = strlen(str);
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_LABEL, IPS200PRO_COMMON_VALUE, (uint8)label_id, (ips200pro_header_struct *)&temp, sizeof(temp), str, temp.length);
return return_state;
}
uint8 ips200pro_label_mode(uint16 label_id, ips200pro_label_mode_enum mode)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = mode;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_LABEL, IPS200PRO_LABEL_LONG_MODE, (uint8)label_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_table_create(int16 x, int16 y, uint16 row_num, uint16 col_num)
{
uint8 return_state = 1;
if(MAX_ID_TABLE > ips200pro_table_num)
{
return_state = ips200pro_create_widgets(++ips200pro_table_num | (IPS200PRO_WIDGETS_TABLE << 8), x, y, row_num, col_num);
if(1 == return_state)
{
ips200pro_table_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_table_num | (IPS200PRO_WIDGETS_TABLE << 8));
}
uint8 ips200pro_table_cell_printf(uint16 table_id, uint8 row, uint8 col, char *format, ...)
{
int32 str_length;
va_list arg;
va_start(arg, format);
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 2);
str_length = vsnprintf(ips200pro_printf_buffer, sizeof(ips200pro_printf_buffer) - 1, format, arg);
if(0 <= str_length)
{
temp.length = (uint32)str_length;
temp.data[0].uint16_data = row;
temp.data[1].uint16_data = col;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_TABLE, IPS200PRO_COMMON_VALUE, (uint8)table_id, (ips200pro_header_struct *)&temp, sizeof(temp), ips200pro_printf_buffer, temp.length);
}
va_end(arg);
return return_state;
}
uint8 ips200pro_table_set_col_width(uint16 table_id, uint8 col, uint16 width)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = width;
temp.data[1].uint16_data = col;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_TABLE, IPS200PRO_TABLE_COL_WIDTH, (uint8)table_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_table_select(uint16 table_id, uint8 row, uint8 col)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = row;
temp.data[1].uint16_data = col;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_TABLE, IPS200PRO_TABLE_SELECT, (uint8)table_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_meter_create(int16 x, int16 y, uint16 size, ips200pro_meter_style_enum style)
{
uint8 return_state = 1;
if(MAX_ID_METER > ips200pro_meter_num)
{
return_state = ips200pro_create_widgets(++ips200pro_meter_num | (IPS200PRO_WIDGETS_METER << 8), x, y, size, style);
if(1 == return_state)
{
ips200pro_meter_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_meter_num | (IPS200PRO_WIDGETS_METER << 8));
}
uint8 ips200pro_meter_set_value(uint16 meter_id, int16 value)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].int16_data = value;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_METER, IPS200PRO_COMMON_VALUE, (uint8)meter_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_clock_create(int16 x, int16 y, uint16 clock_size, ips200pro_clock_style_enum clock_type)
{
uint8 return_state = 1;
if(MAX_ID_CLOCK > ips200pro_clock_num)
{
return_state = ips200pro_create_widgets(++ips200pro_clock_num | (IPS200PRO_WIDGETS_CLOCK << 8), x, y, clock_size, clock_type);
if(1 == return_state)
{
ips200pro_clock_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_clock_num | (IPS200PRO_WIDGETS_CLOCK << 8));
}
uint16 ips200pro_progress_bar_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
if(MAX_ID_PROGRESS_BAR > ips200pro_progress_bar_num)
{
return_state = ips200pro_create_widgets(++ips200pro_progress_bar_num | (IPS200PRO_WIDGETS_BAR << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_progress_bar_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_progress_bar_num | (IPS200PRO_WIDGETS_BAR << 8));
}
uint8 ips200pro_progress_bar_set_value(uint16 progress_bar_id, uint8 start_value, uint8 end_value)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = start_value;
temp.data[1].uint16_data = end_value;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_BAR, IPS200PRO_COMMON_VALUE, (uint8)progress_bar_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_calendar_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state;
// 只能创建一个日历控件
return_state = ips200pro_create_widgets(1 | (IPS200PRO_WIDGETS_CALENDAR << 8), x, y, width, height);
return return_state == 1 ? 0 : (1 | (IPS200PRO_WIDGETS_CALENDAR << 8));
}
uint8 ips200pro_calendar_display(uint16 year, uint8 month, ips200pro_calendar_mode_enum mode)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = year;
temp.data[1].uint8_data[0] = month;
temp.data[1].uint8_data[1] = mode;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_CALENDAR, IPS200PRO_COMMON_VALUE, 1, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_waveform_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
if(MAX_ID_WAVEFORM > ips200pro_waveform_num)
{
return_state = ips200pro_create_widgets(++ips200pro_waveform_num | (IPS200PRO_WIDGETS_WAVEFORM << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_waveform_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_waveform_num | (IPS200PRO_WIDGETS_WAVEFORM << 8));
}
uint8 ips200pro_waveform_add_value(uint16 waveform_id, uint8 line_id, const uint16 *data, uint16 length, uint16 color)
{
uint8 return_state = 1;
if(MAX_ID_WAVEFORM_LINE > line_id - 1)
{
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = line_id;
temp.data[1].uint16_data = color;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_COMMON_VALUE, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), data, length * 2);
}
return return_state;
}
uint8 ips200pro_waveform_line_state(uint16 waveform_id, uint16 line_id, uint16 line_state)
{
uint8 return_state = 1;
if(MAX_ID_WAVEFORM_LINE > line_id - 1)
{
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = line_id;
temp.data[1].uint16_data = line_state;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_WAVEFORM_LINE_STATE, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
}
return return_state;
}
uint8 ips200pro_waveform_line_type(uint16 waveform_id, uint8 line_type)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 1);
temp.data[0].uint16_data = line_type;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_WAVEFORM_LINE_TYPE, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint8 ips200pro_waveform_clear(uint16 waveform_id)
{
uint8 return_state;
ips200pro_header_struct temp;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_WAVEFORM, IPS200PRO_WAVEFORM_CLEAR, (uint8)waveform_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_image_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
if(MAX_ID_IMAGE > ips200pro_image_num)
{
return_state = ips200pro_create_widgets(++ips200pro_image_num | (IPS200PRO_WIDGETS_IMAGE << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_image_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_image_num | (IPS200PRO_WIDGETS_IMAGE << 8));
}
uint8 ips200pro_image_display(uint16 image_id, const void *image, uint16 width, uint16 height, ips200pro_image_type_enum image_type, uint8 threshold)
{
uint8 return_state = 0;
uint16 send_length;
uint32 image_size;
uint8 const *image_data;
IPS200PRO_COMMON_STRUCT(temp, 4);
image_data = (uint8 *)image;
image_size = width * height * (IMAGE_RGB565 == image_type ? 2 : 1);
// 任意条件满足,则表示不需要发送图像数据,仅通知屏幕更新边线或矩形
if((NULL == image) || (!width) || (!height) || (IMAGE_NULL == image_type))
{
temp.data[0].uint16_data = 0;
temp.data[1].uint16_data = 0;
temp.data[2].uint8_data[1] = IMAGE_NULL;
}
else
{
temp.data[0].uint16_data = width;
temp.data[1].uint16_data = height;
temp.data[2].uint8_data[1] = image_type;
}
temp.data[2].uint8_data[0] = 1; // 图像开始传输标志位
temp.data[3].uint16_data = threshold;
do
{
// 计算本次传输字节数
send_length = image_size > (IPS200PRO_SPI_LENGTH - sizeof(temp)) ? (IPS200PRO_SPI_LENGTH - sizeof(temp)) : (uint16)image_size;
return_state += ips200pro_write_packet(IPS200PRO_WIDGETS_IMAGE, IPS200PRO_COMMON_VALUE, (uint8)image_id, (ips200pro_header_struct *)&temp, sizeof(temp), image_data, send_length);
image_data += send_length;
image_size -= send_length;
temp.data[2].uint8_data[0] = 0;
}while(image_size);
return return_state;
}
uint8 ips200pro_image_draw_line(uint16 image_id, uint8 line_id, void *line_data, uint16 line_length, ips200pro_image_line_type_enum data_type, uint16 color)
{
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 2);
if(MAX_ID_IMAGE_LINE >= line_id)
{
temp.length = data_type * line_length * 2 + sizeof(temp);
temp.data[0].uint8_data[0] = line_id;
temp.data[0].uint8_data[1] = data_type;
temp.data[1].uint16_data = color;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_IMAGE, IPS200PRO_IMAGE_DRAW_LINE, (uint8)image_id, (ips200pro_header_struct *)&temp, sizeof(temp), line_data, data_type * line_length * 2);
}
return return_state;
}
uint8 ips200pro_image_draw_rectangle(uint16 image_id, uint8 rectangle_id, int16 x, int16 y, uint16 rectangle_width, uint16 rectangle_height, uint16 color)
{
uint8 return_state = 1;
IPS200PRO_COMMON_STRUCT(temp, 6);
if(MAX_ID_IMAGE_RECTANGLE >= rectangle_id)
{
temp.data[0].uint16_data = rectangle_id;
temp.data[1].int16_data = x;
temp.data[2].int16_data = y;
temp.data[3].uint16_data = rectangle_width;
temp.data[4].uint16_data = rectangle_height;
temp.data[5].uint16_data = color;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_IMAGE, IPS200PRO_IMAGE_DRAW_RECTANGLE, (uint8)image_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
}
return return_state;
}
uint16 ips200pro_container_create(int16 x, int16 y, uint16 width, uint16 height)
{
uint8 return_state = 1;
if(MAX_ID_CONTAINER > ips200pro_container_num)
{
return_state = ips200pro_create_widgets(++ips200pro_container_num | (IPS200PRO_WIDGETS_CONTAINER << 8), x, y, width, height);
if(1 == return_state)
{
ips200pro_container_num--;
}
}
return return_state == 1 ? 0 : (ips200pro_container_num | (IPS200PRO_WIDGETS_CONTAINER << 8));
}
uint8 ips200pro_container_radius(uint16 container_id, uint16 border_width, uint16 radius)
{
uint8 return_state;
IPS200PRO_COMMON_STRUCT(temp, 2);
temp.data[0].uint16_data = border_width;
temp.data[1].uint16_data = radius;
return_state = ips200pro_write_packet(IPS200PRO_WIDGETS_CONTAINER, IPS200PRO_COMMON_VALUE, (uint8)container_id, (ips200pro_header_struct *)&temp, sizeof(temp), NULL, 0);
return return_state;
}
uint16 ips200pro_init(char *str, ips200pro_title_position_enum title_position, uint8 title_size)
{
uint16 page_id = 0;
spi_init(IPS200PRO_SPI_INDEX, SPI_MODE0, IPS200PRO_SPI_SPEED, IPS200PRO_CLK_PIN, IPS200PRO_MOSI_PIN, IPS200PRO_MISO_PIN, SPI_CS_NULL);
gpio_init(IPS200PRO_RST_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
gpio_init(IPS200PRO_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
// 将屏幕应答引脚修改为上拉,这样即使屏幕在使用过程中被拔掉也不会导致程序卡主
gpio_init(IPS200PRO_INT_PIN, GPI, GPIO_HIGH, GPI_PULL_UP);
gpio_set_level(IPS200PRO_RST_PIN, 0);
system_delay_ms(5);
gpio_set_level(IPS200PRO_RST_PIN, 1);
system_delay_ms(20);
ips200pro_lebel_num = 0;
ips200pro_table_num = 0;
ips200pro_meter_num = 0;
ips200pro_clock_num = 0;
ips200pro_progress_bar_num = 0;
ips200pro_waveform_num = 0;
ips200pro_image_num = 0;
ips200pro_container_num = 0;
ips200pro_page_num = 0;
// 某一些主板屏幕接口由于没有MISO引脚,所以无法读取屏幕信息
// ips200pro_get_information(&ips200pro_information);
// ips200pro_get_time(&ips200pro_time);
// 设置时间会立即生效,因此并不建议在初始化中调用时间设置函数,如果在初始化中调用就会导致每次上电之后时间都会还原
// ips200pro_set_time(15, 54, 30);
// 特别注意、特别注意、特别注意
// 设置页面标题显示位置以及标题宽度,需要注意仅在创建页面之前调用才能生效
// 特别注意、特别注意、特别注意
ips200pro_page_set_title_position_width(title_position, title_size);
ips200pro_set_format(IPS200PRO_DEFAULT_FORMAT);
ips200pro_set_default_font(IPS200PRO_DEFAULT_FONT_SIZE);
ips200pro_set_optimize(IPS200PRO_DEFAULT_OPTIMIZE);
// 设置默认参数并创建一个页面
if(NULL != str)
{
page_id = ips200pro_page_create(str); // 创建一个页面
}
#if(1 == IPS200PRO_CRC_ENABLE)
ips200pro_set_crc_state(1); // 使能CRC模式增强抗干扰能力,但是需要消耗主控一部分算力做CRC计算
#endif
return page_id;
}