Files
99_7018_lmx/cpu/br28/umidigi_chargestore.c

142 lines
3.6 KiB
C
Raw Normal View History

2025-10-29 13:10:02 +08:00
#include "asm/umidigi_chargestore.h"
#include "gpio.h"
#include "app_config.h"
#include "timer.h"
#if TCFG_UMIDIGI_BOX_ENABLE
typedef struct _UMIDIGI_VAR {
volatile u16 timer_handle; //消息数据获取函数的定时器句柄
volatile u16 message; //消息体 13bits + 3bits固定为0
void (*app_umidigi_chargetore_message_deal)(u16 message);
} UMIDIGI_VAR;
#define __this (&umidigi_var)
static UMIDIGI_VAR umidigi_var;
void umidigi_chargestore_message_callback(void (*app_umidigi_chargetore_message_deal)(u16 message))
{
__this->app_umidigi_chargetore_message_deal = app_umidigi_chargetore_message_deal;
}
/*对收到的message数据包进行奇校验 message的BIT(3)为crc_odd位*/
static void crc_odd_check(u16 message)
{
u8 one_num = 0, crc_odd = 0;
/* 判断起始位为0和结束位为0 */
if (message & (BIT(0) | BIT(14))) {
r_printf("start bit or stop bit is not zero\n");
return;
}
/* 计算cmd和data一共有几个1 */
for (u8 i = 2; i < 14; i++) {
if (message & BIT(i)) {
one_num ++;
}
}
/* r_printf("one_num = %d\n", one_num); */
/*奇校验计算 crc_odd位于message的BIT(1)*/
if (one_num % 2) {
crc_odd = 0x0;
} else {
crc_odd = 0x2;
}
/* r_printf("crc_odd = %d\n", crc_odd); */
/* r_printf("(message & BIT(1)) = %d\n", (message & BIT(1))); */
/*比对计算出的crc_odd值与实际收到的crc_odd值*/
if ((message & BIT(1)) == crc_odd) {
if (__this->app_umidigi_chargetore_message_deal) {
__this->app_umidigi_chargetore_message_deal(message);
}
} else {
r_printf("message crc check error, received an invalid message!\n");
}
}
/*通过port口电平状态收集充电舱发送的数据*/
static void get_port_status(void *priv)
{
static u8 keep_cnt = 0;
static u8 change_cnt = 0;
static u8 timeout_cnt = 0;
static u8 pre_status = 0;
static u8 message_index = 0;
u8 port_status = gpio_read(TCFG_CHARGESTORE_PORT);
//第一步:判断数据是否超时
timeout_cnt++;
if (timeout_cnt >= (TIMER2CMESSAGE * 16 / 2)) {
goto __end_exit;
}
//第二步:判断IO是否翻转,及状态切换滤波
keep_cnt++;
if (port_status == pre_status) {
change_cnt = 0;
return;
} else {
change_cnt++;
if (change_cnt <= 2) {
return;
}
}
//第三步:判断采集时间是否在范围内,并更新n bit数据
while (keep_cnt) {
if (keep_cnt >= 5) {
if (pre_status) {
__this->message |= BIT(14 - message_index);
}
if (keep_cnt >= 10) {
keep_cnt -= 10;
} else {
keep_cnt = 0;
}
message_index++;
} else {
break;
}
}
pre_status = port_status;
timeout_cnt = 0;
keep_cnt = 0;
change_cnt = 0;
if (message_index < 15) {
return;
}
//第四步:校验数据
r_printf("message = %04x\n", __this->message);
crc_odd_check(__this->message);
__this->message = 0;
__end_exit:
keep_cnt = 0;
change_cnt = 0;
timeout_cnt = 0;
pre_status = 0;
message_index = 0;
usr_timer_del(__this->timer_handle);
__this->timer_handle = 0;
}
/*ldo下降沿唤醒 collect message*/
void ldo_port_wakeup_to_cmessage(void)
{
/*只有通讯口的下降沿唤醒会触发定时器 即数据的起始位*/
if (!__this->timer_handle) {
__this->message = 0;
__this->timer_handle = usr_timer_add(NULL, get_port_status, TIMER2CMESSAGE / 10, 1);
}
}
#endif