-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvcstap.c
271 lines (193 loc) · 5.74 KB
/
vcstap.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
270
#include "vcstap.h"
typedef struct {
int8 revision;
int8 modbus_address;
int8 serial_prefix;
int16 serial_number;
int8 pair_serial_prefix;
int16 pair_serial_number;
int8 sensor_source;
int8 world_to_xbee;
int8 world_to_xport;
} struct_config;
#define VCS_N_REGISTERS 40
typedef struct {
int8 modbus_enable;
int8 modbus_last_error;
int8 factory_unlocked;
int16 telem_age;
int8 xrw2g_packet[128];
int8 xrw2g_buff_pos;
int16 xrw2g_age;
/* VCS data as updated by the CAN bus */
int8 vcs_register [VCS_N_REGISTERS*4]; /* 40 32-bit registers */
int16 vcs_query_age;
int8 vcs_read_lock; /* 1 means nobody can modify the data */
int16 vcs_last_data_age;
int16 led_on_red;
int16 led_on_green;
int8 dump_register;
int8 now_telem;
} struct_timer;
/* global structures */
struct_config config;
struct_timer timer;
#include "can.c"
#include "uart_sci16is740.c"
#include "live.c"
#include "modbus_slave_vcstap.c"
#include "interrupt.c"
#include "param.c"
#include "modbus_handler_vcstap.c"
void init() {
setup_oscillator(OSC_8MHZ | OSC_INTRC);
restart_wdt();
setup_wdt(WDT_ON);
setup_adc(ADC_OFF);
/*
setup_adc_ports(NO_ANALOGS); doesn't seem to work.
Manually set ANCON0 to 0xff and ANCON1 to 0x1f for all digital
*/
// ANCON0=0xff;
// ANCON1=0x1f;
// setup_comparator(NC_NC_NC_NC);
setup_timer_2(T2_DIV_BY_16,61,2); // set 1 millisecond period with 8 MHz oscillator
port_b_pullups(TRUE);
delay_ms(10);
output_low(SYNC_OUT);
timer.modbus_enable=FALSE;
/* xrw2g uart */
uart_init();
/* CAN interface to VCS */
can_init();
/* receive and receiver error interrupts */
enable_interrupts(INT_CANRX0);
enable_interrupts(INT_CANRX1);
enable_interrupts(INT_CANIRX);
/* global structures */
timer.factory_unlocked=0;
timer.telem_age=0;
timer.xrw2g_age=65535;
timer.xrw2g_buff_pos=0;
memset(timer.xrw2g_packet, 0, sizeof(timer.xrw2g_packet));
timer.vcs_read_lock=0;
timer.vcs_query_age=0;
timer.vcs_last_data_age=65535;
memset(timer.vcs_register, 0, sizeof(timer.vcs_register));
timer.dump_register=255;
timer.now_telem=0;
/* receive data from serial ports */
enable_interrupts(INT_RDA); /* inverter */
// enable_interrupts(INT_RDA2); /* world (ethernet or xbee */
/* timer0 is used for modbus handler */
/* 1 millisecond timer */
enable_interrupts(INT_TIMER2);
}
#define interrupt_enabled(x) !!(*(make8(x,1) | 0xF00) & make8(x,0))
void read_data_xrw2g(void) {
int8 c;
if ( uart_kbhit() ) {
while ( uart_kbhit() ) {
// output_high(TP_ORANGE);
c=uart_getc();
// output_low(TP_ORANGE);
timer.xrw2g_age=0;
if ( timer.xrw2g_buff_pos < sizeof(timer.xrw2g_packet) ) {
timer.xrw2g_packet[timer.xrw2g_buff_pos++]=c;
}
}
}
}
void send_can_query(int8 queryRegister) {
unsigned int32 can_id;
unsigned int8 data[4];
/* message ID 3 is query */
can_id=(int32) 3;
data[0]=queryRegister;
data[1]=0x00;
data[2]=0x00;
data[3]=0x00;
if ( 0 == can_putd(can_id,data,4,0,FALSE,FALSE) ) {
/* on error */
can_abort();
can_init();
// timer.led_on_red=50;
}
}
/* this is started after the bootloader is done loading or times out */
void main(void) {
int8 last;
last=restart_cause();
/* normal device startup */
init();
read_param_file();
write_default_param_file();
/* initial watchdog restart. Subsequently only restart in live send */
restart_wdt();
/* set relay to be initially off (indicating fault). vcs live send then controls there after */
output_low(RELAY_RED);
/* modbus_init turns on global interrupts */
// modbus_init();
enable_interrupts(GLOBAL);
fprintf(rs232,"# (world) vcstap.c %s - my serial %c%lu -",__DATE__,config.serial_prefix,config.serial_number);
switch ( last ) {
case WDT_TIMEOUT: fprintf(rs232,"WDT_TIMEOUT\r\n"); break;
case MCLR_FROM_SLEEP: fprintf(rs232,"MCLR_FROM_SLEEP\r\n"); break;
case MCLR_FROM_RUN: fprintf(rs232,"MCLR_FROM_RUN\r\n"); break;
case NORMAL_POWER_UP: fprintf(rs232,"NORMAL_POWER_UP\r\n"); break;
case BROWNOUT_RESTART: fprintf(rs232,"BROWNOUT_RESTART\r\n"); break;
case WDT_FROM_SLEEP: fprintf(rs232,"WDT_FROM_SLEEP\r\n"); break;
case RESET_INSTRUCTION: fprintf(rs232,"RESET_INSTRUCTION\r\n"); break;
default: fprintf(rs232,"UNKNOWN CAUSE\r\n");
}
// fprintf(rs232,"# (rs232) vcstap.c %s - my serial %c%lu\r\n",__DATE__,config.serial_prefix,config.serial_number);
/* fast red, yellow, green */
timer.led_on_red =200;
delay_ms(160);
timer.led_on_green=400;
delay_ms(160);
timer.led_on_red=0;
delay_ms(160);
timer.led_on_green=0;
last=0;
/* main loop */
for ( ; ; ) {
// restart_wdt();
/* read data from our different sources */
read_data_xrw2g();
/* transmit buffer empty */
if ( can_tbe() && timer.vcs_query_age>=25 ) {
/* loop through our list of registers */
if ( last == VCS_N_REGISTERS )
last=0;
send_can_query(last++);
timer.vcs_query_age=0;
}
/*
* every 10 seconds we send a sync pulse which should trigger another packet from XRW2G
*/
if ( timer.now_telem ) {
timer.now_telem=0;
// output_high(SYNC_OUT);
live_send_vcs();
// output_high(TP_ORANGE);
} else {
output_low(SYNC_OUT);
// output_low(TP_ORANGE);
}
/* we have XRW2G data, and we haven't gotten any more in last 50 miliseconds */
if ( 0 != timer.xrw2g_buff_pos && timer.xrw2g_age > 50 ) {
#if 1
live_send_xrw2g();
#else
fprintf(rs232,"# XRW2G %c%lu ",timer.xrw2g_packet[1],make16(timer.xrw2g_packet[2],timer.xrw2g_packet[3]));
if ( 0 == live_send_xrw2g() ) {
fprintf(rs232,"error-%c%lu ",timer.xrw2g_packet[1],make16(timer.xrw2g_packet[2],timer.xrw2g_packet[3]));
} else {
fprintf(rs232,"success-%c%lu ",timer.xrw2g_packet[1],make16(timer.xrw2g_packet[2],timer.xrw2g_packet[3]));
}
timer.telem_age=0;
#endif
}
}
}