function_broadcast.c
6.16 KB
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
/*
广播数据(信标)
基站协议V0.95 section2.3设置发信息信标
键盘协议V0.99-11 section 2.4 广播信息信标
*/
#include "base_core_user.h"
#include "string.h"
#include "function.h"
#include "function_interface.h"
#define SLOT_MAX 255//128 //Max is 0xff from protocol!!
struct content_STR{
//2.3.2发送的内容
unsigned char dcmd;
unsigned char slotmax;
// unsigned char slotn;
unsigned char data[SLOT_MAX][16]; //128,Max=0xff
};
struct broadcast_STR{
//2.3.1发送参数
unsigned char type;
unsigned char times;
unsigned char slots;
//2.3.2发送的内容
struct content_STR content[2];
//2.3.3启动发送和结果
unsigned char id_sn_broad;
unsigned char id_sn[6];
unsigned char startup_dcmd;
//user var
unsigned char on_off_flag;
unsigned char execute_times;
unsigned char slot_seq;
unsigned char cur_type;
//keypad request
unsigned char keypad_request_step;
unsigned char data_pos;
};
struct broadcast_STR broadcast={
.data_pos =0,
};
/* --------------------------------------------------------
基站保存来自sdk的广播数据
*/
void broadcast_config(const unsigned char *rx_pc)
{
unsigned char type;//题型
// unsigned char ack_flag=1;
unsigned char ack_buf[20]={1};
unsigned char ack_buf_len=1;
switch(rx_pc[3]){
case 11:
memcpy(&broadcast.type,rx_pc+4,3);
break;
case 12:
//20200811,增加sdk从基站读回题型数据。基站部分V0.96 section2.3.2
//if( (rx_pc[4] !=1) && (rx_pc[4] !=2) ) break;
if( (rx_pc[4] ==1) || (rx_pc[4] ==2) )
{
if( rx_pc[6] >=SLOT_MAX) break;//防止数组溢出
type=rx_pc[4]-1;
broadcast.content[type].dcmd = rx_pc[4];
broadcast.cur_type =type;
broadcast.content[type].slotmax =rx_pc[5];
memcpy(&broadcast.content[type].data[rx_pc[6]] ,rx_pc+7,16);
}
else if(rx_pc[4] &0x80){ //sdk读题型数据
if( rx_pc[6] >=SLOT_MAX) break;//防止数组溢出
type=(rx_pc[4]&~0x80) -1;
ack_buf[1] =broadcast.content[type].slotmax; //byte5
ack_buf[2] =rx_pc[6];
memcpy(ack_buf+3,&broadcast.content[type].data[rx_pc[6]] ,16);
ack_buf_len =19;
}
break;
case 13:
memcpy(&broadcast.id_sn_broad,rx_pc+4,8);
break;
default:ack_buf_len=0;break;
}//sw
if(ack_buf_len)
user__pc_cmd_ack(0x60,rx_pc[3],ack_buf,ack_buf_len);
}
//unsigned char broad_cast_cnt;
/*---------------------------------------------
发送广播信标子函数
input:
type -题型
seq -数据包号
*/
static void base_broadcast_sub(unsigned char type,unsigned char seq)
{
unsigned char tmp[32+1];
tmp[0] = 32;//31;
base_core.get_match_code(tmp+1);
tmp[5] = ( base_core.get_log_mode() <=3)?0x31:0x32; //id or SN
tmp[6] = 0x00;
tmp[7] = 0x00;
//byte8-11 Keypad SN
// tmp[12] = broadcast.content[type].dcmd | (broadcast.data_pos <<4); //DCMD,High 4bit is datapos
tmp[12] = (broadcast.content[type].dcmd&0x0f) | (base_core.get_vote_datapos() <<4); //DCMD,High 4bit is datapos
tmp[13] = 0;
tmp[14] =broadcast.content[type].slotmax ;//slotMax
tmp[15] = seq; //broadcast.content[type].slotn ; //slot_seq
memcpy(tmp+16,broadcast.content[type].data[seq],16);
tmp[32] =crc16(tmp+5,27)&0xff; //CRC
//broad_cast_cnt++;
#ifdef _DEBUG_CORE_
SEGGER_RTT_printf(0,"pd:%02x,seq:%d\n",tmp[12],tmp[15]);
#endif
base_core.send_rf_data(tmp,base_core.get_mainRF_hard_id());
}
/*
启动广播的条件
a,监测到 测验题-多题型; 表决器V0.99-11 section2.2.13
b,接收到 键盘没有收齐数据的 请求; 教育新版-表决器V0.99-11 section3.2.6
*/
void startup_broadcast(void)
{
if( !function.BROADCAST__SW) return;
if(broadcast.on_off_flag==1) return; //如果正在进行广播信息,就不要再启动了!!!!
base_core.switch_send_beacon(0);// turn off send beacon
broadcast.data_pos++;
broadcast.on_off_flag =1;
broadcast.execute_times = 0;
broadcast.slot_seq =0;
// broadcast.cur_type =0;//由进入的模式决定debug only
}
/*
//2021.05.10 客诉描述:多题型模式下,重新拔插基站后导致键盘无法开机--其实是键盘显示白屏;
原因:多题型模式下,题型内容不保存,拔插基站后题型内容丢失;但是还是在多题型模式下。
解决办法:在开始广播多题型时,增加判断是否存在题型内容;如果没有就强制退出并切换到空闲模式下。
*/
unsigned char det_blank_content(void)
{
if( (broadcast.content[0].slotmax==0) &&(broadcast.content[1].slotmax==0) ){
//force exit multi content,exit sysmode0;
broadcast.on_off_flag =0;
base_core.force_sysmode0();
base_core.switch_send_beacon(1);
return 1;
}
return 0;
}
/*----------------------------------------------------------
* 特殊处理 来自键盘的“广播信息不完整”的请求;
* 基站收到键盘请求后,需要按正常周期给键盘ack,然后才开始启动广播发送;
* 当然如果当前正在发广播信号,就不必再启动发送了!!
*具体做法:在发送基础/投票信标时(此时基站一定是已经发送了对键盘请求的ack)判断是如果收到了键盘请求,就开启广播模式;
* input:request =1 ,接收键盘申请输入参数;other:startup
* return
*/
unsigned char process_keypad_broadcast_requst(unsigned char request)
{
if( !function.BROADCAST__SW) return 0;
if( request ==1){
if(det_blank_content() ) return 0;
broadcast.keypad_request_step = request;
}
else{
if(broadcast.keypad_request_step){
broadcast.keypad_request_step=0;
startup_broadcast();
return 1;
}
}
return 0;
}
unsigned char led_cnt;//debug only
/*
called by 2.5ms and turn off send beacon!!
*/
void base_broadcast_process_2ms5(void)
{
if( !function.BROADCAST__SW) return;
if( !broadcast.on_off_flag) return;
if(broadcast.slot_seq >= SLOT_MAX) return;
base_broadcast_sub(broadcast.cur_type,broadcast.slot_seq);
// if(++led_cnt>=3){//debug only
// led_cnt=0;
// operation_debug_io(5);//debug only
// }
if(++broadcast.slot_seq >= broadcast.content[broadcast.cur_type].slotmax ){
//发送完一个周期了;
broadcast.slot_seq =0;
if(++broadcast.execute_times >=10){
broadcast.on_off_flag=0;
base_core.switch_send_beacon(1);
}
}
}