g0b1vetx-board/Application/displaythread.c
2023-11-30 08:10:01 +08:00

668 lines
15 KiB
C
Raw 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.

#include "main.h"
#include "os-app.h"
#include <stdio.h>
#include <rtthread.h>
#include "usart-board.h"
#include "disdefine.h"
#include "data.h"
#include <ef_api.h>
ALIGN (RT_ALIGN_SIZE)
static char thread_stack[4096];
static struct rt_thread display_thread;
static rt_timer_t timer;
static struct
{
char userpwd[8];
char syspwd[8];
char device_id[10];
int identity;
} s_driver;
static void view_rx_done (void)
{
rt_event_send (gUartEvents, EVENT_UART_VIEW_RX);
//rt_kprintf ("m4851_rx_done!\r\n");
}
static void view_tx_data (uint8_t * data, uint16_t length)
{
rt_event_send (gUartEvents, EVENT_UART_VIEW_RX);
//rt_kprintf ("m4851_rx_done!\r\n");
}
static int timerout_timer = 0;
static void timerouter (void * parameter)
{
TypeIndexMail_t mail;
timerout_timer ++;
if (timerout_timer > 100) // 超过90s 没有收到数据,重启网络
{
mail.Type = MAIL_VIEW_FLUSH;
rt_mb_send (gViewMail, * ( (uint32_t*) &mail));
timerout_timer = 0;
}
}
static int DisPreparePacket (DisDataType_t ddtt, char *buf, int maxLen)
{
int tx_size = 0;
buf[tx_size++] = 0x5A;
buf[tx_size++] = 0xA5;
buf[tx_size++] = 0x00; // 数据长度
switch (ddtt.type)
{
case DIS_TYPE_WD_INT:
{
buf[tx_size++] = 0x82;
buf[tx_size++] = ddtt.Addr.Byte[1]; // 寄存器地址高位
buf[tx_size++] = ddtt.Addr.Byte[0]; // 寄存器地址高位
buf[tx_size++] = ddtt.Int.Byte[3]; // 寄存器数据高位
buf[tx_size++] = ddtt.Int.Byte[2]; // 寄存器数据高位
buf[tx_size++] = ddtt.Int.Byte[1]; // 寄存器数据高位
buf[tx_size++] = ddtt.Int.Byte[0]; // 寄存器数据高位
break;
}
case DIS_TYPE_WD_FLOAT:
{
buf[tx_size++] = 0x82;
buf[tx_size++] = ddtt.Addr.Byte[1]; // 寄存器地址高位
buf[tx_size++] = ddtt.Addr.Byte[0]; // 寄存器地址高位
buf[tx_size++] = ddtt.Float.Byte[3]; // 寄存器数据高位
buf[tx_size++] = ddtt.Float.Byte[2]; // 寄存器数据高位
buf[tx_size++] = ddtt.Float.Byte[1]; // 寄存器数据高位
buf[tx_size++] = ddtt.Float.Byte[0]; // 寄存器数据高位
break;
}
case DIS_TYPE_SWPAGE:
{
buf[tx_size++] = 0x82;
buf[tx_size++] = 0x00;
buf[tx_size++] = 0x84;
buf[tx_size++] = 0x5a;
buf[tx_size++] = 0x01;
buf[tx_size++] = ddtt.Int.Byte[1]; // 寄存器数据高位
buf[tx_size++] = ddtt.Int.Byte[0]; // 寄存器数据高位
break;
}
case DIS_TYPE_RD:
{
buf[tx_size++] = 0x83;
buf[tx_size++] = ddtt.Addr.Byte[1]; // 寄存器地址高位
buf[tx_size++] = ddtt.Addr.Byte[0]; // 寄存器地址高位
buf[tx_size++] = ddtt.Len;
break;
}
// 10 70 05 30 30 30 30 30 30 30 31 FF FF
case DIS_TYPE_WD_BYTES:
{
buf[tx_size++] = 0x82;
buf[tx_size++] = ddtt.Addr.Byte[1]; // 寄存器地址高位
buf[tx_size++] = ddtt.Addr.Byte[0]; // 寄存器地址高位
for (int i = 0; i < ddtt.Len; i++)
{
buf[tx_size++] = ddtt.bytes[i];
}
break;
}
case DIS_TYPE_WD_ICON:
{
buf[tx_size++] = 0x82;
buf[tx_size++] = ddtt.Addr.Byte[1]; // 寄存器地址高位
buf[tx_size++] = ddtt.Addr.Byte[0]; // 寄存器地址高位
buf[tx_size++] = ddtt.Int.Byte[1]; // 寄存器数据高位
buf[tx_size++] = ddtt.Int.Byte[0]; // 寄存器数据高位
break;
}
default:
break;
}
buf[2] = tx_size - 3;
return tx_size;
}
static void disctrl_handle (char *data, int length)
{
DisDataType_t ddtt;
int index = 0, a = 0, tx_size ;
uint16_t cmd, addr;
char txbuf[100];
char setstr[32];
TypeIndexMail_t mail;
cmd = data[index++];
addr = ( (uint16_t) data[index] << 8) + (uint16_t) data[index + 1];
index += 2; // 去掉地址
index++;
if (cmd == 0x83) // 屏幕上报的数据
{
rt_kprintf ("command:%04X\r\n", addr);
switch (addr)
{
//
// 5A A5 06 83 20 10 01 00 00
case DIS_CMD_BTN_SLOP: // 开度提闸界面 - 执行
{
mail.Type = MAIL_VIEW_READSL;
rt_mb_send (gViewMail, * ( (uint32_t*) &mail));
//rt_event_send (gUIEvents, EVENT_VIEW_READSL);
break;
}
case DIS_CMD_BTN_DUP: // 调试界面上升
{
mail.Type = MAIL_SLUICE_SUP;
mail.index = 0;
rt_mb_send (gSluiceMail, * ( (uint32_t*) &mail));
break;
}
case DIS_CMD_BTN_DDOWN: // 调试界面下降
{
mail.Type = MAIL_SLUICE_SDW;
mail.index = 0;
rt_mb_send (gSluiceMail, * ( (uint32_t*) &mail));
break;
}
case DIS_CMD_BTN_DSTOP: // 调试界面停止
{
mail.Type = MAIL_SLUICE_STP;
mail.index = 0;
rt_mb_send (gSluiceMail, * ( (uint32_t*) &mail));
break;
}
case DIS_CMD_BTN_DUNLOCK: // 调试界面解锁
{
if (s_driver.identity == 0) // 用户无此权限
{
break;
}
rt_event_send (gCtrlEvents, EVENT_CTRL_SET_UNLOCK); // 开锁
break;
}
case DIS_CMD_BTN_FACT:
{
if (s_driver.identity == 0)
{
break;
}
ef_env_set_default();
break;
}
case DIS_CMD_BTN_REST:
{
if (s_driver.identity == 0)
{
break;
}
HAL_NVIC_SystemReset();
break;
}
case DIS_CMD_BTN_SETMAX: // 设置为最大值
{
// 将最大值写入flash
rt_sprintf (setstr, "%d", SluiceData[0].ecode);
ef_set_env ("max_ecode", setstr);
break;
}
case DIS_CMD_BTN_SETMIN: // 设置为最小值
{
rt_sprintf (setstr, "%d", SluiceData[0].ecode);
ef_set_env ("min_ecode", setstr);
break;
}
// 5A A5 0A 83 10 30 03 30 31 32 33 FF FF
case DIS_CNUM_PASS:
{
if ( (rt_memcmp (&data[index], (char *) s_driver.userpwd, 6) == 0)) // 用户密码
{
s_driver.identity = 0;
ddtt.type = DIS_TYPE_SWPAGE;
ddtt.Int.Int = 0x0004;
tx_size = DisPreparePacket (ddtt, txbuf, 100);
MX_UART_PutBuffer (&g_ViewDrv, txbuf, tx_size);
}
if ( (rt_memcmp (&data[index], (char *) s_driver.syspwd, 6) == 0)) // 用户密码
{
s_driver.identity = 1;
ddtt.type = DIS_TYPE_SWPAGE;
ddtt.Int.Int = 0x0004;
tx_size = DisPreparePacket (ddtt, txbuf, 100);
MX_UART_PutBuffer (&g_ViewDrv, txbuf, tx_size);
}
break;
}
// 设置提闸开度
case DIS_CNUM_SLSET:
{
a = (uint16_t) data[index + 2] * 256 + (uint16_t) data[index + 3];
SluiceData[0].sopen = a * 10;
//SluiceData[gMqttDrv.rx_index].sopen = datak / 10;
mail.Type = MAIL_SLUICE_OPT;
mail.index = 0;
rt_mb_send (gSluiceMail, * ( (uint32_t*) &mail));
//rt_event_send (gCtrlEvents, EVENT_CTRL_SET_OPT_SLU);
break;
}
// 83 10 70 05 30 30 30 31 30 30 30 31 FF FF
case DIS_CASCII_DEVID: // 设置设备编码
{
if (s_driver.identity == 0) // 验证身份,不是管理员不允许修改参数
{
break;
}
//char addr[11];
//rt_sprintf(addr, "%*.s", 10, &data[index]);
ef_save_string ("device_id", &data[index], 10);
break;
}
case DIS_CASCII_PASS:
{
if (s_driver.identity == 0)
{
break;
}
// if (s_user_role != 1)
// break;
// if (length != 12)
// {
// DisWritePass (SysInfo.LoginPass, QUEUE);
// return;
// }
// // 校验密码的合法性,只能出现数字
// for (int i = 0; i < 6; i++)
// {
// if (data[index + i] > '9' || data[index + i] < '0')
// {
// DisWritePass (SysInfo.LoginPass, QUEUE);
// return;
// }
// }
// SysSetLoginPass ( (char *) &data[index], length - 6);
break;
}
// case DIS_CSPEED_SLSPEED: // 提闸速度分为10级直流驱动器提闸速度似乎没什么用太小了都提不动
// {
// break;
// }
case DIS_CNUM_SLHEIGHT: // 修改最大开度
{
if (s_driver.identity == 0)
{
break;
}
union
{
uint32_t Int;
uint8_t Byte[4];
} Int;
Int.Byte[3] = data[index++];
Int.Byte[2] = data[index++];
Int.Byte[1] = data[index++];
Int.Byte[0] = data[index++];
rt_sprintf (setstr, "%d", Int.Int);
ef_set_env ("max_open", setstr);
break;
}
default:
break;
}
}
else // 0x82
{
switch (addr)
{
case DIS_CMD_DOW_SUCC:
{
// dbg_printf("DIS_CMD_DOW_SUCC\r\n");
break;
}
default:
break;
}
}
}
// 更新累计流量
static void dis_write_ttflow (uint32_t ttflow)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.Addr.addr = DIS_CNUM_TTFLOW;
ddtt.type = DIS_TYPE_WD_INT;
ddtt.Int.Int = ttflow;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 更新瞬时流量
static void dis_write_mmflow (float mmFlow)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.Addr.addr = DIS_CNUM_FLOW;
ddtt.type = DIS_TYPE_WD_FLOAT;
ddtt.Float.Float = mmFlow;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 更新瞬时流速
static void dis_write_mmspeed (float mmSpeed)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.Addr.addr = DIS_CNUM_SPEED;
ddtt.type = DIS_TYPE_WD_FLOAT;
ddtt.Float.Float = mmSpeed;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 更新闸门开度
void dis_write_open (float open)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.Addr.addr = DIS_CNUM_SLGET;
ddtt.type = DIS_TYPE_WD_FLOAT;
ddtt.Float.Float = open;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 更新闸门荷重
void dis_write_load (float load)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_FLOAT;
ddtt.Addr.addr = DIS_CNUM_SLLOADKEY;
ddtt.Float.Float = load;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 更新编码器值
void dis_write_code (uint32_t ecode)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.Addr.addr = DIS_CNUM_DBG_ECODE;
ddtt.type = DIS_TYPE_WD_INT;
ddtt.Int.Int = ecode;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 闸门最大开度
void dis_write_slmaxopen (uint32_t ecode)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.Addr.addr = DIS_CNUM_SLHEIGHT;
ddtt.type = DIS_TYPE_WD_INT;
ddtt.Int.Int = ecode;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 发送给屏幕设备编号
// 参数1:设备编号
// 参数2:是否通过队列写入
static void dis_write_divice_id (char * id)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_BYTES;
ddtt.Addr.addr = DIS_CASCII_DEVID;
ddtt.Len = 10;
char * c = ef_get_env ("device_id");
rt_memcpy (ddtt.bytes, c, 10);
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 发送给屏幕设备编号
// 参数1:设备编号
// 参数2:是否通过队列写入
static void dis_write_ipaddr (char *ipaddr)
{
DisDataType_t ddtt;
char tx_buf[128], p;
// 2、 IP地址
ddtt.type = DIS_TYPE_WD_BYTES;
ddtt.Addr.addr = DIS_CASCII_IP;
ddtt.Len = strlen (ipaddr);
rt_sprintf (ddtt.bytes, "%s", ipaddr);
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 发送给屏幕设备编号
// 参数1:端口
// 参数2:是否通过队列写入
void dis_write_ipport (int port)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_INT;
ddtt.Addr.addr = DIS_CASCII_PORT;
ddtt.Int.Int = port;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 发送给屏幕登录密码
// 参数1:端口
// 参数2:是否通过队列写入
void dis_write_usrpwd (char *pass)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_BYTES;
ddtt.Addr.addr = DIS_CASCII_PASS;
ddtt.Len = strlen (pass);
rt_sprintf ( (char *) ddtt.bytes, "%s", pass);
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 修改网络状态
void dis_write_net_ste (int ste)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_ICON;
ddtt.Addr.addr = DIS_CSTE_NET;
ddtt.Int.Int = ste;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 修改电机状态
void dis_write_motor_ste (int ste, int isqueue)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_ICON;
ddtt.Addr.addr = DIS_CSTE_MOTOR;
ddtt.Int.Int = ste;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 修改编码器状态
static void dis_write_plus_ste (int ste)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_ICON;
ddtt.Addr.addr = DIS_CSTE_PLUS;
ddtt.Int.Int = ste;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 切换页面
static void dis_write_page (uint32_t Page)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_SWPAGE;
ddtt.Int.Int = Page;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
// 修改编码器状态
void diw_write_load_ste (int ste)
{
DisDataType_t ddtt;
char tx_buf[128], p;
ddtt.type = DIS_TYPE_WD_ICON;
ddtt.Addr.addr = DIS_CSTE_LOAD;
ddtt.Int.Int = ste;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
}
static void thread_entry (void * argument)
{
char tx_buf[128], p;
DisDataType_t ddtt;
rt_kprintf ("%s was start!\r\n", __FILE__);
g_ViewDrv.rxdone = view_rx_done;
g_ViewDrv.BaudRate = 115200;
MX_UART_Init (&g_ViewDrv);
TypeIndexMail_t mail;
timer = rt_timer_create ("distimer", timerouter, RT_NULL, 10, RT_TIMER_FLAG_PERIODIC); // 异常检测定时器
char * s ;
s = ef_get_env ("user_pass");
rt_sprintf (s_driver.userpwd, "%s", s);
s = ef_get_env ("sys_pass");
rt_sprintf (s_driver.syspwd, "%s", s);
s_driver.identity = 0;
s = ef_get_env ("max_open");
int32_t max_open = atoi (s);
// 载入参数
dis_write_divice_id ( (char *) s_driver.device_id);
dis_write_ipaddr ("mqtt.zyjzjs.cn");
dis_write_ipport (1883);
dis_write_usrpwd ( (char *) s_driver.userpwd);
dis_write_slmaxopen (max_open);
dis_write_page (1); // 初始化完成,跳转到第一页显示
dis_write_plus_ste (0);
dis_write_net_ste (0);
dis_write_load (0);
dis_write_code (SluiceData[0].ecode);
rt_timer_start (timer);
while (1)
{
if (rt_mb_recv (gViewMail, (rt_ubase_t*) &mail, RT_WAITING_NO) == RT_EOK)
{
switch (mail.Type)
{
case MAIL_VIEW_FLUSH:
// 刷新闸门开度
dis_write_open ( (float) SluiceData[0].gopen / 10);
dis_write_load (0);
dis_write_mmflow (0);
dis_write_mmspeed (0);
dis_write_ttflow (0);
dis_write_code (SluiceData[0].ecode);
break;
case MAIL_VIEW_READSL:
ddtt.type = DIS_TYPE_RD;
ddtt.Addr.addr = DIS_CNUM_SLSET;
ddtt.Len = 2;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
break;
case MAIL_VIEW_LOGIN: // 登录
break;
case MAIL_VIEW_NET_STE:
ddtt.type = DIS_TYPE_WD_ICON;
ddtt.Addr.addr = DIS_CSTE_NET;
ddtt.Int.Int = mail.index;
p = DisPreparePacket (ddtt, tx_buf, 128);
MX_UART_PutBuffer (&g_ViewDrv, tx_buf, p);
break;
default:
break;
}
}
// 更新网络状态
if (RT_EOK == rt_event_recv (gUartEvents, EVENT_UART_VIEW_RX, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, 300, RT_NULL)) // 数据接受失败,上报异常状态
{
for (int i = 0; i < g_ViewDrv.rx_size; i++)
{
if (g_ViewDrv.rx_buffer[i] == 0x5A)
{
if ( (g_ViewDrv.rx_buffer[i] == 0x5A) && (g_ViewDrv.rx_buffer[i + 1] == 0xA5)) // 如果是1
{
int dataLen = g_ViewDrv.rx_buffer[i + 2];
disctrl_handle (&g_ViewDrv.rx_buffer[i + 3], dataLen);
}
}
}
MX_UART_Clear (&g_ViewDrv);
}
rt_thread_mdelay (10);
}
}
void DisThreadStart (void)
{
/* 创建线程1名称是thread1入口是thread1_entry*/
rt_thread_init (&display_thread, "display_thread",
thread_entry, RT_NULL,
&thread_stack[0],
sizeof (thread_stack),
U4851M_THREAD_PRIORITY, U4851M_THREAD_TIMESLICE);
rt_thread_startup (&display_thread);
return ;
}