AC7006&AD6973充电仓通讯-高低电平

高低电平通信

新增文件 ldoin_commu.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#include "app_config.h"
#include "system/includes.h"
#include "ldoin_commu.h"
#include "app_main.h"
#include "asm/pwm_led.h"

#ifdef CONFIG_DEBUG_LITE_ENABLE
#include "debug_lite.h"
#define ldo_comm_printf printf_lite
#else
#define ldo_comm_printf printf
#endif

/**
* 起始帧{a=100ms,b=100ms},1是{d=20ms,f=20ms},0是{c=20ms,e=20ms,g=20ms},结束帧h=300ms
* <-a-><b><c d e f g><-h-> 有效数据是cdef,g固定为0
* ___ _ _ ____
* | | | | | | | |
* ____| |_| |_| |_| |
*/
#if USER_CHARGESTORE_COMM_EN
#define TIMER_CNT_UNIT 85 //us
#define TIMER_OUT_MS 500 //ms

#define MS_TO_CNT(ms, offset) (((ms*1000) + (offset*1000))/TIMER_CNT_UNIT)

static volatile s32 low_level = 0; //低电平时间
static volatile s32 high_level = 0; //高电平时间
static volatile u8 get_leader = 0; //获取到起始帧标志
static volatile u8 comm_timeout = 1; //通信超时标志
static volatile u8 data_byte = 0x00; //通信数据暂存变量
static volatile u8 bit_cnt = 0; //当前获取到的bit数
static volatile u8 user_comm_data_buff[16] = {0}; //当前获取到的数据缓存
static volatile u8 user_comm_data_len = 0; //当前获取到的数据缓存长度
static volatile u8 prev_edge = 0xff;

/**
* @brief 定时器中断函数
*
*/
___interrupt
void user_comm_timeout(void)
{
JL_TIMER3->CON |= BIT(14);
comm_timeout = 1;
get_leader = 0;
JL_TIMER3->CON &= ~BIT(0);
ldo_comm_printf("user_comm_timeout\n");
}

/**
* @brief 通信定时器初始化
*
*/
void user_comm_init(void)
{
ldo_comm_printf("user_comm_init\n");
low_level = 0;
high_level = 0;
get_leader = 0;
comm_timeout = 1;
bit_cnt = 0;
JL_TIMER3->CON = 0;
bit_clr_ie(IRQ_TIME3_IDX);
request_irq(IRQ_TIME3_IDX, 5, user_comm_timeout, 0);
JL_TIMER3->CNT = 0;
JL_TIMER3->PRD = TIMER_OUT_MS*1000/TIMER_CNT_UNIT + 1;
JL_TIMER3->CON |= BIT(14);
JL_TIMER3->CON = ((6 << 10) | (13 << 4));
}

/**
* @brief 通信定时器重启
*
*/
void user_comm_restart(void)
{
JL_TIMER3->CON = 0;
JL_TIMER3->CNT = 0;
JL_TIMER3->PRD = TIMER_OUT_MS*1000/TIMER_CNT_UNIT + 1;
JL_TIMER3->CON |= BIT(14);
JL_TIMER3->CON = ((6 << 10) | (13 << 4) | BIT(0));
}

/**
* @brief 通信状态复位
*
*/
void user_comm_reset(void)
{
low_level = 0;
high_level = 0;
get_leader = 0;
comm_timeout = 0;
bit_cnt = 0;
JL_TIMER3->CON = 0;
JL_TIMER3->CNT = 0;
JL_TIMER3->PRD = TIMER_OUT_MS*1000/TIMER_CNT_UNIT + 1;
JL_TIMER3->CON |= BIT(14);
JL_TIMER3->CON = ((6 << 10) | (13 << 4) | BIT(0));
}

/**
* @brief 通信完成
*
*/
void ldoin_comm_end_do(void)
{
ldo_comm_printf("V\n");
if(user_comm_data_len){
put_buf(user_comm_data_buff, user_comm_data_len);
}
}

void extern_send_cover_status(u8 state);
void ldoin_data_cap(u8 edge)
{
//if(get_leader == 0 && high_level > MS_TO_CNT(100, -10) && high_level < MS_TO_CNT(100, 30) && low_level > MS_TO_CNT(100, -10) && low_level < MS_TO_CNT(100, 10)){
if(get_leader == 0 && edge == RISING_EDGE && low_level > MS_TO_CNT(55, -20) && low_level < MS_TO_CNT(55, 20)){
get_leader = 1; //comm begin;
user_comm_data_len = 0;
bit_cnt = 0;
data_byte = 0;
// if(high_level > MS_TO_CNT(100, 10)){
// high_level -= MS_TO_CNT(100, 0);
// goto __data_cap;
// }
high_level = 0;
low_level = 0;
ldo_comm_printf("comm get start\n");
}
else if(get_leader){
if(edge == FALLING_EDGE){
// __data_cap:
u8 bit_n_h = high_level / MS_TO_CNT(20, -5);
u8 bit_n_l = 1 + high_level / MS_TO_CNT(20, 5);
u8 bit_n = (bit_n_h + bit_n_l) >> 1;
if(bit_n < 3){
for (u8 i = 0; i < bit_n; i++)
{
data_byte |= 0x01;
bit_cnt++;
ldo_comm_printf("get 1\n");
if(bit_cnt == 8){
if(data_byte & 0x01){
ldo_comm_printf("comm maybe err\n");
get_leader = 0;
return;
}
data_byte >>= 1;
ldo_comm_printf("comm get %x\n", data_byte);
extern_send_cover_status(data_byte);
get_leader = 0;
return;
}
else{
data_byte = data_byte << 1;
}
}
}
else{
goto __err;
}
return;
}
else if(edge == RISING_EDGE){
u8 bit_n_h = low_level / MS_TO_CNT(20, -5);
u8 bit_n_l = 1 + low_level / MS_TO_CNT(20, 5);
u8 bit_n = (bit_n_h + bit_n_l) >> 1;
if(bit_n < 3){
for (u8 i = 0; i < bit_n; i++)
{
data_byte |= 0x00;
bit_cnt++;
ldo_comm_printf("get 0\n");
if(bit_cnt == 8){
if(data_byte & 0x01){
ldo_comm_printf("comm maybe err\n");
get_leader = 0;
return;
}
data_byte >>= 1;
ldo_comm_printf("comm get %x\n", data_byte);
extern_send_cover_status(data_byte);
get_leader = 0;
return;
}
else{
data_byte = data_byte << 1;
}
}
}
else{
goto __err;
}
}
return;
__err:
ldo_comm_printf("comm maybe err\n");
get_leader = 0;
return;
}
}

/**
* @brief 电平跳变中断处理
*
* @param index 唤醒源序号
* @param gpio 唤醒源所在IO
* @param edge 唤醒沿
*/
void ldoin_isr_user_comm_deal(u8 index, u8 gpio, u8 edge)
{
if(gpio == IO_LDOIN_DET){
if(comm_timeout || prev_edge == 0xff){
prev_edge = edge;
user_comm_reset();
return;
}
else if(edge == FALLING_EDGE){
if(prev_edge == RISING_EDGE){
high_level = JL_TIMER3->CNT;
ldo_comm_printf("h:%d\n", high_level);
}
user_comm_restart();
}
else if(edge == RISING_EDGE){
if(prev_edge == FALLING_EDGE){
low_level = JL_TIMER3->CNT;
ldo_comm_printf("l:%d\n", low_level);
}
user_comm_restart();
}
prev_edge = edge;
ldoin_data_cap(edge);
}
else{
ldo_comm_printf("gpio %d edge %d\n", gpio, edge);
}
}

/**
* @brief 获取通信忙状态
*
* @return u8
*/
u8 chargestore_get_comm_busy_flag(void)
{
return get_leader;
}


#else
u8 chargestore_get_comm_busy_flag(void)
{
return 0;
}

void user_comm_init(void)
{

}

void ldoin_isr_user_comm_deal(u8 index, u8 gpio, u8 edge)
{

}

#endif

新增文件ldoin_commu.h

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef __LDOIN_COMMU__
#define __LDOIN_COMMU__

#define USER_CHARGESTORE_COMM_EN 1

#define BOX_LOW_GOTO_POWER_OFF 0

void user_comm_init(void);

void ldoin_isr_user_comm_deal(u8 index, u8 gpio, u8 edge);

#endif

收到信息处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
* 收数处理demo
*/
void extern_send_cover_status(u8 state)
{
switch (state)
{
case 0x05:
log_info("open cid\n");
__this->power_status = 1;
__this->cover_status = 1;
__this->close_ing = 0;
if (__this->switch2bt == 0) {
chargestore_event_to_user(NULL, DEVICE_EVENT_CHARGE_STORE, CMD_POWER_LEVEL_OPEN, 0);
}
break;
case 0x06:
log_info("shut down\n");
__this->power_status = 0;
__this->cover_status = 0;
__this->close_ing = 0;
if(__this->shutdown_timer){
sys_hi_timer_del(__this->shutdown_timer);
}
__this->shutdown_timer = sys_hi_timer_add(NULL, chargestore_shutdown_do, 1000);
break;
case 0x0a:
log_info("close cid\n");
__this->power_status = 1;
__this->cover_status = 0;
chargestore_event_to_user(NULL, DEVICE_EVENT_CHARGE_STORE, CMD_CLOSE_CID, 0);
break;

default:
break;
}
}

公共修改点

修改ldoin中断滤波为不滤波

0af77ef858e08802eb548def5deb657c

d030954c0c0d3665d46c8571f33407f1

38971edf7ff942554adfa274f043672e

697系列要修改 ldoin_isr_user_comm_deal执行的位置

img

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void ldoin_isr_user_comm_deal(u8 index, u8 gpio, u8 edge);
void sub_wakeup_isr(void)
{
static u8 old_edge = 0xff;
u8 edge = FALLING_EDGE;
if(LDO5V_DET_GET()){
edge = RISING_EDGE;
}
printf(" %s %d\n", __func__, !edge);
if(edge != old_edge){
ldoin_isr_user_comm_deal(0xff, IO_LDOIN_DET, edge);
old_edge = edge;
}
if (__this->ldo5v_timer == 0) {
__this->ldo5v_timer = usr_timer_add(0, ldo5v_detect, 2, 1);
}
}