142 lines
3.6 KiB
C
142 lines
3.6 KiB
C
|
|
#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
|
||
|
|
|