root / Version 1.3 / RS232_MUX.X / main.c @ master
Historique | Voir | Annoter | Télécharger (14,634 ko)
1 |
/*
|
---|---|
2 |
* File: main.c
|
3 |
* Author: eniro
|
4 |
* Version : 0.9
|
5 |
*
|
6 |
* Created on March 25, 2024, 3:51 PM
|
7 |
*/
|
8 |
|
9 |
|
10 |
|
11 |
/*
|
12 |
|
13 |
TODO LIST :
|
14 |
*
|
15 |
*
|
16 |
* Remap all pins !!!
|
17 |
*
|
18 |
* Select UART1 as master port
|
19 |
*
|
20 |
* Rename VCOMA/2/3/4 as VCOMA/B/C/D ?
|
21 |
|
22 |
*/
|
23 |
|
24 |
#define F_CPU 24000000UL |
25 |
|
26 |
#include <xc.h> |
27 |
#include <math.h> |
28 |
#include <stdlib.h> |
29 |
#include <util/delay.h> |
30 |
#include <avr/interrupt.h> |
31 |
#include <avr/eeprom.h> |
32 |
|
33 |
#include "hardware_uart.h" |
34 |
#include "hardware_timer.h" |
35 |
#include "hardware_TL16C754C.h" |
36 |
#include "hardware_config.h" |
37 |
#include "frame_definitions.h" |
38 |
#include "parameters.h" |
39 |
|
40 |
//USART setup
|
41 |
|
42 |
//To calculate BAUD value register -> BAUD = 64*FCLK/(16*FBAUDS)
|
43 |
#define UART_BAUD_VALUE 833 // 10000 is equivalent as 9600 bauds (on 24MHz clock) according to datasheet |
44 |
#define USART0_REG 0x3 |
45 |
#define BOOT_MSG "RS232-MUX\r\n" |
46 |
|
47 |
|
48 |
|
49 |
//OSC. setup
|
50 |
#define FREQSEL 0x9 |
51 |
#define _FREQSEL_REG_WR ((FREQSEL) << 2) |
52 |
#define _USART0_REG_WR (USART0_REG & 0x7) |
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
enum portIndex {
|
60 |
PORT_VCOMA_INDEX = 0,
|
61 |
PORT_VCOMB_INDEX, |
62 |
PORT_VCOMC_INDEX, |
63 |
PORT_VCOMD_INDEX, |
64 |
PORT_MCOM_INDEX, |
65 |
}; |
66 |
|
67 |
|
68 |
//////////////////////////////////////////////////////////////
|
69 |
//Prototypes
|
70 |
|
71 |
void bootSequence(void); |
72 |
void MCOM_sendframe(uint8_t *data, uint8_t n, uint8_t port);
|
73 |
void VCOM_sendframe(uint8_t *data, uint8_t n);
|
74 |
void senseDebugLeds(bool *hasWritten, bool *hasRead); |
75 |
|
76 |
//reset watchdog counter
|
77 |
#define WATCHDOG_RESET asm("WDR") |
78 |
|
79 |
uint8_t global_debugBuffer[256];
|
80 |
uint8_t global_n = 0;
|
81 |
uint8_t global_parity; |
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
#ifdef USE_PORT_1
|
89 |
#define INIT_PORT(w,x,y,z) initPort1(w,x,y,z)
|
90 |
#define TX_WRITE(x) txWrite1(x)
|
91 |
#define RX_READ rxRead1()
|
92 |
#define PORT_AVAILABLE portAvailable1()
|
93 |
#else
|
94 |
#ifdef USE_PORT_2
|
95 |
#define INIT_PORT(w,x,y,z) initPort2(w,x,y,z)
|
96 |
#define TX_WRITE(x) txWrite2(x)
|
97 |
#define RX_READ rxRead2()
|
98 |
#define PORT_AVAILABLE portAvailable2()
|
99 |
#else
|
100 |
#ifdef USE_PORT_3
|
101 |
#define INIT_PORT(w,x,y,z) initPort3(w,x,y,z)
|
102 |
#define TX_WRITE(x) txWrite3(x)
|
103 |
#define RX_READ rxRead3()
|
104 |
#define PORT_AVAILABLE portAvailable3()
|
105 |
#else
|
106 |
#ifdef USE_PORT_4
|
107 |
#define INIT_PORT(w,x,y,z) initPort4(w,x,y,z)
|
108 |
#define TX_WRITE(x) txWrite4(x)
|
109 |
#define RX_READ rxRead4()
|
110 |
#define PORT_AVAILABLE portAvailable4()
|
111 |
#else
|
112 |
#error "Please choose an uart port..." |
113 |
#endif
|
114 |
#endif
|
115 |
#endif
|
116 |
#endif
|
117 |
|
118 |
|
119 |
int main(void) { |
120 |
|
121 |
|
122 |
uint8_t ctrlReg; |
123 |
uint8_t masterBuffer[64], bufferA[64], bufferB[64], bufferC[64], bufferD[64]; |
124 |
uint8_t VCOMAIndex = 0, VCOMBIndex = 0, VCOMCIndex = 0, VCOMDIndex = 0, MCOMIndex; |
125 |
uint16_t MCOM_counter = 0;
|
126 |
uint16_t VCOMA_counter = 0;
|
127 |
uint16_t VCOMB_counter = 0;
|
128 |
uint16_t VCOMC_counter = 0;
|
129 |
uint16_t VCOMD_counter = 0;
|
130 |
uint8_t debug; |
131 |
|
132 |
bool writtenStatus = false; |
133 |
bool readStatus[] = {false, false, false, false, false}; |
134 |
|
135 |
setWait(5000);
|
136 |
|
137 |
|
138 |
for(int i = 0; i < 64; i++) |
139 |
{ |
140 |
bufferA[i] = 0;
|
141 |
} |
142 |
for(int i = 0; i < 64; i++) |
143 |
{ |
144 |
bufferB[i] = 0;
|
145 |
} |
146 |
for(int i = 0; i < 64; i++) |
147 |
{ |
148 |
bufferC[i] = 0;
|
149 |
} |
150 |
for(int i = 0; i < 64; i++) |
151 |
{ |
152 |
bufferD[i] = 0;
|
153 |
} |
154 |
|
155 |
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, _FREQSEL_REG_WR); //switch to 24 MHz
|
156 |
|
157 |
|
158 |
|
159 |
//Enable pins (Port direction)
|
160 |
ADDR_ENABLE; //Address pins
|
161 |
ENABLE_WR_RD_PINS; //Read and Write pins
|
162 |
ENABLE_CS_PINS; //Chip select pins
|
163 |
ENABLE_RESET_PIN; //Reset pin
|
164 |
|
165 |
//////////////////////////////////////////////////////////////
|
166 |
//Remember to put high level on cs pins to disable devices...
|
167 |
SETCSA; |
168 |
SETCSB; |
169 |
SETCSC; |
170 |
SETCSD; |
171 |
//Also don't forget IOR and IOW
|
172 |
SETWR; |
173 |
SETRD; |
174 |
//////////////////////////////////////////////////////////////
|
175 |
|
176 |
|
177 |
////////////////////////////////////////
|
178 |
//init TL16C IC
|
179 |
SETRST; |
180 |
//_delay_ms(10);
|
181 |
setWait(100);
|
182 |
CLRRST; |
183 |
setWait(5);
|
184 |
////////////////////////////////////////
|
185 |
|
186 |
//Init virtual COM ports
|
187 |
//TODO : Set EEPROM CFG here
|
188 |
initPortA(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT); |
189 |
initPortB(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT); |
190 |
initPortC(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT); |
191 |
initPortD(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT); |
192 |
|
193 |
//Master Port
|
194 |
INIT_PORT(UART_BAUD_VALUE, F8BIT_MODE, ONE_STOPBIT, AVR32_NO_PARITY); |
195 |
|
196 |
setWait(500);
|
197 |
ctrlReg = 0;
|
198 |
|
199 |
|
200 |
timerInit(60000); //10 ms interrupt |
201 |
sei(); //never forget to enable global interrupt mask !
|
202 |
|
203 |
PORTA.DIR = 0x3F;
|
204 |
|
205 |
|
206 |
|
207 |
while(1) |
208 |
{ |
209 |
if(vcom_choose > 3) |
210 |
{ |
211 |
asm("nop"); |
212 |
asm("nop"); |
213 |
asm("nop"); |
214 |
asm("nop"); |
215 |
} |
216 |
debug++; |
217 |
|
218 |
if(debug == 0x07) |
219 |
asm("nop"); |
220 |
|
221 |
////////////////////////////////////////////////////////
|
222 |
//Read UART A
|
223 |
|
224 |
|
225 |
if(portA_available()) //Check if one byte available |
226 |
{ |
227 |
readStatus[PORT_VCOMA_INDEX] = true;
|
228 |
bufferA[VCOMAIndex] = rxReadA(); |
229 |
VCOMAIndex++; |
230 |
//if(VCOMAIndex > 64)
|
231 |
// VCOMAIndex = 0;
|
232 |
VCOMA_counter = 0; //for frame timeout |
233 |
} |
234 |
|
235 |
////////////////////////////////////////////////////////
|
236 |
//Read UART B
|
237 |
|
238 |
|
239 |
if(portB_available()) //Check if one byte available |
240 |
{ |
241 |
readStatus[PORT_VCOMB_INDEX] = true;
|
242 |
bufferB[VCOMBIndex] = rxReadB(); |
243 |
VCOMBIndex++; |
244 |
//if(VCOMBIndex > 64)
|
245 |
// VCOMBIndex = 0;
|
246 |
VCOMB_counter = 0; //for frame timeout |
247 |
} |
248 |
|
249 |
|
250 |
////////////////////////////////////////////////////////
|
251 |
//Read UART C
|
252 |
|
253 |
|
254 |
if(portC_available()) //Check if one byte available |
255 |
{ |
256 |
readStatus[PORT_VCOMC_INDEX] = true;
|
257 |
bufferC[VCOMCIndex] = rxReadC(); |
258 |
VCOMCIndex++; |
259 |
//if(VCOMCIndex > 64)
|
260 |
// VCOMCIndex = 0;
|
261 |
VCOMC_counter = 0; //for frame timeout |
262 |
} |
263 |
|
264 |
|
265 |
|
266 |
////////////////////////////////////////////////////////
|
267 |
//Read UART D
|
268 |
|
269 |
|
270 |
if(portD_available()) //Check if one byte available |
271 |
{ |
272 |
readStatus[PORT_VCOMD_INDEX] = true;
|
273 |
bufferD[VCOMDIndex] = rxReadD(); |
274 |
VCOMDIndex++; |
275 |
//if(VCOMDIndex > 64)
|
276 |
// VCOMDIndex = 0;
|
277 |
VCOMD_counter = 0; //for frame timeout |
278 |
} |
279 |
|
280 |
|
281 |
////////////////////////////////////////////////////////
|
282 |
//Read UART Master
|
283 |
|
284 |
|
285 |
if(PORT_AVAILABLE > 0) //check if we have bytes to read |
286 |
{ |
287 |
readStatus[PORT_MCOM_INDEX] = true;
|
288 |
masterBuffer[MCOMIndex] = RX_READ; //store byte into buffer
|
289 |
MCOMIndex++; //increment to next byte
|
290 |
//if(MCOMIndex > 64)
|
291 |
// MCOMIndex = 0;
|
292 |
MCOM_counter = 0; //refresh timeout counter |
293 |
} |
294 |
|
295 |
|
296 |
|
297 |
|
298 |
//Timed process (for leds, etc...)
|
299 |
if(getTimerFlag())
|
300 |
{ |
301 |
/////////////////////////////////////////////////////////
|
302 |
//Timeout process
|
303 |
|
304 |
//For master port
|
305 |
if(MCOMIndex > 0) |
306 |
MCOM_counter++; |
307 |
|
308 |
//For virtual port 1
|
309 |
if(VCOMAIndex > 0) |
310 |
VCOMA_counter++; |
311 |
|
312 |
//For virtual port 2
|
313 |
if(VCOMBIndex > 0) |
314 |
VCOMB_counter++; |
315 |
|
316 |
//For virtual port 3
|
317 |
if(VCOMCIndex > 0) |
318 |
VCOMC_counter++; |
319 |
|
320 |
//For virtual port 4
|
321 |
if(VCOMDIndex > 0) |
322 |
VCOMD_counter++; |
323 |
|
324 |
|
325 |
senseDebugLeds(&writtenStatus, readStatus); |
326 |
clearTimerFlag(); |
327 |
} |
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
///////////////////////////////////////
|
334 |
//When buf is ready from master
|
335 |
if(MCOM_counter > SERIAL_PORT_TIMEOUT_COUNT || MCOMIndex >= 64) |
336 |
{ |
337 |
//Send buffer to VCOM
|
338 |
VCOM_sendframe(masterBuffer, MCOMIndex); |
339 |
MCOMIndex = 0; //reset index buffer |
340 |
MCOM_counter = 0; //reset counter |
341 |
} |
342 |
|
343 |
|
344 |
///////////////////////////////////////
|
345 |
//When buf is ready from VCOMA
|
346 |
|
347 |
if(VCOMA_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMAIndex >= 64) |
348 |
{ |
349 |
writtenStatus = true;//Say a wrote has been made |
350 |
//Send buffer to VCOM
|
351 |
MCOM_sendframe(bufferA, VCOMAIndex, PORT_VCOMA_INDEX); |
352 |
VCOMAIndex = 0; //reset index buffer |
353 |
VCOMA_counter = 0; //reset counter |
354 |
} |
355 |
|
356 |
|
357 |
|
358 |
///////////////////////////////////////
|
359 |
//When buf is ready from VCOMB
|
360 |
|
361 |
if(VCOMB_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMBIndex >= 64) |
362 |
{ |
363 |
//Send buffer to VCOM
|
364 |
MCOM_sendframe(bufferB, VCOMBIndex, PORT_VCOMB_INDEX); |
365 |
VCOMBIndex = 0; //reset index buffer |
366 |
VCOMB_counter = 0; //reset counter |
367 |
} |
368 |
|
369 |
|
370 |
///////////////////////////////////////
|
371 |
//When buf is ready from VCOMC
|
372 |
if(VCOMC_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMCIndex >= 64) |
373 |
{ |
374 |
writtenStatus = true;//Say a wrote has been made |
375 |
//Send buffer to VCOM
|
376 |
MCOM_sendframe(bufferC, VCOMCIndex, PORT_VCOMC_INDEX); |
377 |
VCOMCIndex = 0; //reset index buffer |
378 |
VCOMC_counter = 0; //reset counter |
379 |
} |
380 |
|
381 |
|
382 |
|
383 |
|
384 |
if(VCOMD_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMDIndex >= 64) |
385 |
{ |
386 |
|
387 |
writtenStatus = true; //Say a wrote has been made |
388 |
//Send buffer to VCOM
|
389 |
MCOM_sendframe(bufferD, VCOMDIndex, PORT_VCOMD_INDEX); |
390 |
VCOMDIndex = 0; //reset index buffer |
391 |
VCOMD_counter = 0; //reset counter |
392 |
} |
393 |
|
394 |
|
395 |
///////////////////////////////////////////////////////////
|
396 |
//Priority check
|
397 |
|
398 |
//Check if buffer is empty, then put port at lowest priority !
|
399 |
|
400 |
if(VCOMAIndex == 0) //no buffer ? |
401 |
{ |
402 |
vcom_priority[PORT_VCOMA_INDEX] = 0; //no priority |
403 |
} |
404 |
|
405 |
|
406 |
if(VCOMBIndex == 0) //no buffer ? |
407 |
{ |
408 |
vcom_priority[PORT_VCOMB_INDEX] = 0; //no priority |
409 |
} |
410 |
|
411 |
|
412 |
if(VCOMCIndex == 0) //no buffer ? |
413 |
{ |
414 |
vcom_priority[PORT_VCOMC_INDEX] = 0; //no priority |
415 |
} |
416 |
|
417 |
|
418 |
if(VCOMDIndex == 0) //no buffer ? |
419 |
{ |
420 |
vcom_priority[PORT_VCOMD_INDEX] = 0; //no priority |
421 |
} |
422 |
|
423 |
|
424 |
} |
425 |
|
426 |
|
427 |
|
428 |
return 0; |
429 |
} |
430 |
|
431 |
|
432 |
|
433 |
|
434 |
///////////////////////////////////////////////////////////
|
435 |
//Functions / macros
|
436 |
|
437 |
//Send a frame from virtual port to master port
|
438 |
|
439 |
void MCOM_sendframe(uint8_t *data, uint8_t n, uint8_t port)
|
440 |
{ |
441 |
//////////////////////////
|
442 |
//Send frame
|
443 |
|
444 |
TX_WRITE(0x02); //STX |
445 |
TX_WRITE(port + CESAR_SHIFT); //Which virtual port called master port ?
|
446 |
TX_WRITE(FRAME_ADDR_1); //ADDR
|
447 |
TX_WRITE(FRAME_ADDR_2); //ADDR
|
448 |
|
449 |
for(uint8_t i = 0; i < n; i++) //DATA |
450 |
TX_WRITE(data[i]); |
451 |
|
452 |
TX_WRITE(LF_CHAR); //End of frame
|
453 |
TX_WRITE(CR_CHAR); //End of frame
|
454 |
//////////////////////////
|
455 |
} |
456 |
|
457 |
//////////////////////////////////////////////////////////////////////////////////////////
|
458 |
//Send a frame from master port to virtual port (that calculate whose port to send ?)
|
459 |
|
460 |
void VCOM_sendframe(uint8_t *data, uint8_t n)
|
461 |
{ |
462 |
uint16_t addrFunctions[] = {&txWriteA, &txWriteB, &txWriteC, &txWriteD }; //list of available functions addresses
|
463 |
void (*localTxWrite)(); //function pointer |
464 |
|
465 |
////////////////////////////////
|
466 |
//To debugger read section
|
467 |
|
468 |
|
469 |
|
470 |
for(int i = 0; i < 256; i++) |
471 |
global_debugBuffer[i] = data[i]; |
472 |
|
473 |
if(global_n == 0x02) |
474 |
{ |
475 |
asm("nop"); |
476 |
} |
477 |
if(global_debugBuffer[1] == 0x03) |
478 |
{ |
479 |
asm("nop"); |
480 |
} |
481 |
////////////////////////////////
|
482 |
|
483 |
//At first, check if first byte is the start of text
|
484 |
if(data[0] == STX) |
485 |
{ |
486 |
if(data[2] == FRAME_ADDR_1 && data[3] == FRAME_ADDR_2) //check if we have the MUX address identifier |
487 |
{ |
488 |
if(data[n-1] == CR_CHAR) //check the end of text (second byte) |
489 |
{ |
490 |
if(data[n-2] == LF_CHAR) //check the end of text (first byte) |
491 |
{ |
492 |
data[1]-=CESAR_SHIFT; //convert port index to buffer equivalent |
493 |
localTxWrite = addrFunctions[(data[1] < 3) ? data[1] : 3 ]; //data[3] |
494 |
for(int i = 4; i < n-2; i++) //send frame without (STX + FRAME_ADDR_B1 + FRAME_ADDR_B2 + LF_CHAR + CR_CHAR) |
495 |
{ |
496 |
localTxWrite(data[i]); |
497 |
} |
498 |
|
499 |
} |
500 |
} |
501 |
} |
502 |
} |
503 |
} |
504 |
|
505 |
|
506 |
|
507 |
|
508 |
|
509 |
|
510 |
|
511 |
void bootSequence(void) |
512 |
{ |
513 |
debugLedsTest(); |
514 |
} |
515 |
|
516 |
|
517 |
|
518 |
|
519 |
/**
|
520 |
<p><b>void debugLedsTest(void)</b></p>
|
521 |
<p><b>Debug leds test sequence</b></p>
|
522 |
*/
|
523 |
void debugLedsTest(void) |
524 |
{ |
525 |
|
526 |
PORTA.OUT = 1;
|
527 |
for(int i = 0; i < 6; i++) |
528 |
{ |
529 |
PORTA.OUT <<= 1;
|
530 |
_delay_ms(125);
|
531 |
} |
532 |
PORTA.OUT = 0;
|
533 |
} |
534 |
|
535 |
/**
|
536 |
<p><b>void senseDebugLeds(void)</b></p>
|
537 |
<p><b>Call this to update leds status</b></p>
|
538 |
*/
|
539 |
void senseDebugLeds(bool *hasWritten, bool *hasRead) |
540 |
{ |
541 |
|
542 |
|
543 |
|
544 |
///////////////////////////
|
545 |
//Check Master Port
|
546 |
if(*hasWritten)
|
547 |
{ |
548 |
PORTA.OUT |= 0x20;
|
549 |
*hasWritten = false;
|
550 |
} |
551 |
else
|
552 |
PORTA.OUT &= ~(0x20);
|
553 |
|
554 |
if(hasRead[PORT_MCOM_INDEX])
|
555 |
{ |
556 |
PORTA.OUT |= 0x10;
|
557 |
hasRead[PORT_MCOM_INDEX] = false;
|
558 |
} |
559 |
else
|
560 |
PORTA.OUT &= ~(0x10);
|
561 |
|
562 |
///////////////////////////
|
563 |
//Check VCOMA
|
564 |
if(hasRead[PORT_VCOMA_INDEX])
|
565 |
{ |
566 |
PORTA.OUT |= 0x01;
|
567 |
hasRead[PORT_VCOMA_INDEX] = false;
|
568 |
} |
569 |
else
|
570 |
PORTA.OUT &= ~(0x01);
|
571 |
|
572 |
///////////////////////////
|
573 |
//Check VCOMB
|
574 |
if(hasRead[PORT_VCOMB_INDEX])
|
575 |
{ |
576 |
PORTA.OUT |= 0x02;
|
577 |
hasRead[PORT_VCOMB_INDEX] = false;
|
578 |
} |
579 |
else
|
580 |
PORTA.OUT &= ~(0x02);
|
581 |
|
582 |
///////////////////////////
|
583 |
//Check VCOMC
|
584 |
if(hasRead[PORT_VCOMC_INDEX])
|
585 |
{ |
586 |
PORTA.OUT |= 0x04;
|
587 |
hasRead[PORT_VCOMC_INDEX] = false;
|
588 |
} |
589 |
else
|
590 |
PORTA.OUT &= ~(0x04);
|
591 |
|
592 |
|
593 |
///////////////////////////
|
594 |
//Check VCOMD
|
595 |
if(hasRead[PORT_VCOMD_INDEX])
|
596 |
{ |
597 |
PORTA.OUT |= 0x08;
|
598 |
hasRead[PORT_VCOMD_INDEX] = false;
|
599 |
} |
600 |
else
|
601 |
PORTA.OUT &= ~(0x08);
|
602 |
} |
603 |
|
604 |
|
605 |
|
606 |
|
607 |
|
608 |
|
609 |
|
610 |
|