Statistiques
| Branche: | Révision:

root / Version 1.2 / RS232_MUX.X / main.c @ master

Historique | Voir | Annoter | Télécharger (17,439 ko)

1 95a3914f Enzo Niro
/*
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
uint8_t getPriority(uint8_t chosen_com, uint8_t *ports_list, uint8_t n);
76
77
//reset watchdog counter
78
#define WATCHDOG_RESET      asm("WDR")
79
80
uint8_t global_debugBuffer[256];
81
uint8_t global_n = 0;
82
uint8_t global_parity;
83
84
85
86
87
88
89
#ifdef USE_PORT_1
90
#define INIT_PORT(w,x,y,z)               initPort1(w,x,y,z)
91
#define TX_WRITE(x)                     txWrite1(x)
92
#define RX_READ                         rxRead1()
93
#define PORT_AVAILABLE                  portAvailable1()
94
#else
95
#ifdef USE_PORT_2
96
#define INIT_PORT(w,x,y,z)               initPort2(w,x,y,z)
97
#define TX_WRITE(x)                     txWrite2(x)
98
#define RX_READ                         rxRead2()
99
#define PORT_AVAILABLE                  portAvailable2()
100
#else
101
#ifdef USE_PORT_3
102
#define INIT_PORT(w,x,y,z)               initPort3(w,x,y,z)
103
#define TX_WRITE(x)                     txWrite3(x)
104
#define RX_READ                         rxRead3()
105
#define PORT_AVAILABLE                  portAvailable3()
106
#else
107
#ifdef USE_PORT_4
108
#define INIT_PORT(w,x,y,z)               initPort4(w,x,y,z)
109
#define TX_WRITE(x)                     txWrite4(x)
110
#define RX_READ                         rxRead4()
111
#define PORT_AVAILABLE                  portAvailable4()
112
#else
113
#error "Please choose an uart port..."
114
#endif
115
#endif
116
#endif
117
#endif
118
119
120
int main(void) {
121
    
122
    
123
    uint8_t ctrlReg;
124
    uint8_t masterBuffer[64], bufferA[64], bufferB[64], bufferC[64], bufferD[64];
125
    uint8_t VCOMAIndex = 0, VCOMBIndex = 0, VCOMCIndex = 0, VCOMDIndex = 0, MCOMIndex;
126
    uint16_t MCOM_counter = 0;
127
    uint16_t VCOMA_counter = 0;
128
    uint16_t VCOMB_counter = 0;
129
    uint16_t VCOMC_counter = 0;
130
    uint16_t VCOMD_counter = 0;
131
    uint8_t debug;
132
    
133
    bool writtenStatus = false;
134
    bool readStatus[] = {false, false, false, false, false};
135
    //local timer counter for local process (blink led, ect...)
136
    
137
    uint8_t vcom_priority[] = {0, 0, 0, 0}; //VCOM priority to send on master port
138
    uint8_t vcom_choose = PORT_VCOMA_INDEX;
139
    
140
    setWait(5000);
141
    
142
    
143
    for(int i = 0; i < 64; i++)
144
    {
145
        bufferA[i] = 0;
146
    }
147
    for(int i = 0; i < 64; i++)
148
    {
149
        bufferB[i] = 0;
150
    }
151
    for(int i = 0; i < 64; i++)
152
    {
153
        bufferC[i] = 0;
154
    }
155
    for(int i = 0; i < 64; i++)
156
    {
157
        bufferD[i] = 0;
158
    }
159
    
160
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, _FREQSEL_REG_WR); //switch to 24 MHz
161
    
162
    
163
    
164
    //Enable pins (Port direction)
165
    ADDR_ENABLE;        //Address pins
166
    ENABLE_WR_RD_PINS;  //Read and Write pins
167
    ENABLE_CS_PINS;     //Chip select pins
168
    ENABLE_RESET_PIN;   //Reset pin
169
    
170
    //////////////////////////////////////////////////////////////
171
    //Remember to put high level on cs pins to disable devices...
172
    SETCSA;
173
    SETCSB;
174
    SETCSC;
175
    SETCSD;
176
    //Also don't forget IOR and IOW
177
    SETWR;
178
    SETRD;
179
    //////////////////////////////////////////////////////////////
180
    
181
    
182
    ////////////////////////////////////////
183
    //init TL16C IC
184
    SETRST; 
185
    //_delay_ms(10);
186
    setWait(100);
187
    CLRRST;
188
    setWait(5);
189
    ////////////////////////////////////////
190
    
191
    //Init virtual COM ports
192
    //TODO : Set EEPROM CFG here
193
    initPortA(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
194
    initPortB(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
195
    initPortC(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
196
    initPortD(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
197
    
198
    //Master Port
199
    INIT_PORT(UART_BAUD_VALUE, F8BIT_MODE, ONE_STOPBIT, AVR32_NO_PARITY);
200
    
201
    setWait(500);
202
    ctrlReg = 0;
203
    
204
    
205
    timerInit(60000); //10 ms interrupt
206
    sei(); //never forget to enable global interrupt mask !
207
    
208
    PORTA.DIR = 0x3F;
209
    
210
    
211
    
212
    while(1)
213
    {
214
        if(vcom_choose > 3)
215
        {
216
                asm("nop");
217
                asm("nop");
218
                asm("nop");
219
                asm("nop");
220
        }
221
        debug++;
222
        
223
        if(debug == 0x07)
224
            asm("nop");
225
        
226
        ////////////////////////////////////////////////////////
227
        //Read UART A
228
        
229
        
230
        if(portA_available()) //Check if one byte available
231
        {
232
            readStatus[PORT_VCOMA_INDEX] = true;
233
            bufferA[VCOMAIndex] = rxReadA(); 
234
            VCOMAIndex++; 
235
            //if(VCOMAIndex > 64)
236
            //    VCOMAIndex = 0;
237
            VCOMA_counter = 0; //for frame timeout
238
        }
239
        
240
        ////////////////////////////////////////////////////////
241
        //Read UART B
242
        
243
        
244
        if(portB_available()) //Check if one byte available
245
        {
246
            readStatus[PORT_VCOMB_INDEX] = true;
247
            bufferB[VCOMBIndex] = rxReadB();
248
            VCOMBIndex++; 
249
            //if(VCOMBIndex > 64)
250
            //    VCOMBIndex = 0;
251
            VCOMB_counter = 0; //for frame timeout  
252
        }
253
        
254
        
255
        ////////////////////////////////////////////////////////
256
        //Read UART C
257
        
258
        
259
        if(portC_available()) //Check if one byte available
260
        {
261
            readStatus[PORT_VCOMC_INDEX] = true;
262
            bufferC[VCOMCIndex] = rxReadC();
263
            VCOMCIndex++; 
264
            //if(VCOMCIndex > 64)
265
            //    VCOMCIndex = 0;
266
            VCOMC_counter = 0; //for frame timeout 
267
        }
268
        
269
        
270
        
271
        ////////////////////////////////////////////////////////
272
        //Read UART D
273
        
274
        
275
        if(portD_available()) //Check if one byte available
276
        {
277
            readStatus[PORT_VCOMD_INDEX] = true;
278
            bufferD[VCOMDIndex] = rxReadD();
279
            VCOMDIndex++; 
280
            //if(VCOMDIndex > 64)
281
            //    VCOMDIndex = 0;
282
            VCOMD_counter = 0; //for frame timeout
283
        }
284
        
285
        
286
        ////////////////////////////////////////////////////////
287
        //Read UART Master
288
        
289
        
290
        if(PORT_AVAILABLE > 0) //check if we have bytes to read
291
        {
292
            readStatus[PORT_MCOM_INDEX] = true;
293
            masterBuffer[MCOMIndex] = RX_READ; //store byte into buffer
294
            MCOMIndex++; //increment to next byte
295
            //if(MCOMIndex > 64)
296
            //    MCOMIndex = 0;
297
            MCOM_counter = 0; //refresh timeout counter
298
        }
299
        
300
        
301
        
302
303
        //Timed process (for leds, etc...)
304
        if(getTimerFlag())
305
        {
306
            /////////////////////////////////////////////////////////
307
            //Timeout process
308
309
            //For master port
310
            if(MCOMIndex > 0)
311
                MCOM_counter++;
312
313
            //For virtual port 1
314
            if(VCOMAIndex > 0)
315
                VCOMA_counter++;
316
317
            //For virtual port 2
318
            if(VCOMBIndex > 0)
319
                VCOMB_counter++;
320
321
            //For virtual port 3
322
            if(VCOMCIndex > 0)
323
                VCOMC_counter++;
324
325
            //For virtual port 4
326
            if(VCOMDIndex > 0)
327
                VCOMD_counter++;
328
            
329
            
330
            senseDebugLeds(&writtenStatus, readStatus);
331
            clearTimerFlag();
332
        }
333
        
334
        
335
            
336
        
337
        
338
        ///////////////////////////////////////
339
        //When buf is ready from master
340
        if(MCOM_counter > SERIAL_PORT_TIMEOUT_COUNT || MCOMIndex >= 64)
341
        {         
342
            
343
            
344
            
345
            //Send buffer to VCOM
346
            VCOM_sendframe(masterBuffer, MCOMIndex);
347
            MCOMIndex = 0; //reset index buffer
348
            MCOM_counter = 0; //reset counter
349
        }
350
        
351
        
352
        ///////////////////////////////////////
353
        //When buf is ready from VCOMA
354
        
355
        if(vcom_choose == PORT_VCOMA_INDEX)
356
        {
357
            if(VCOMA_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMAIndex >= 64)
358
            {
359
360
                vcom_choose = getPriority(vcom_choose, vcom_priority, MAX_VCOM_PORTS); //Calculate next port to send
361
362
                if(vcom_choose > 3)
363
                {
364
                    asm("nop");
365
                    asm("nop");
366
                    asm("nop");
367
                    asm("nop");
368
                }
369
                
370
                writtenStatus = true;//Say a wrote has been made
371
                //Send buffer to VCOM
372
                MCOM_sendframe(bufferA, VCOMAIndex, PORT_VCOMA_INDEX);
373
                VCOMAIndex = 0; //reset index buffer
374
                VCOMA_counter = 0; //reset counter
375
            }
376
        }
377
        
378
        
379
        
380
        ///////////////////////////////////////
381
        //When buf is ready from VCOMB
382
        if(vcom_choose == PORT_VCOMB_INDEX)
383
        {
384
            if(VCOMB_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMBIndex >= 64)
385
            {
386
387
                vcom_choose = getPriority(vcom_choose, vcom_priority, MAX_VCOM_PORTS); //Calculate next port to send
388
389
                if(vcom_choose > 3)
390
                {
391
                    asm("nop");
392
                    asm("nop");
393
                    asm("nop");
394
                    asm("nop");
395
                }
396
                
397
                writtenStatus = true;//Say a wrote has been made
398
                //Send buffer to VCOM
399
                MCOM_sendframe(bufferB, VCOMBIndex, PORT_VCOMB_INDEX);
400
                VCOMBIndex = 0; //reset index buffer
401
                VCOMB_counter = 0; //reset counter
402
            }
403
        }
404
        
405
        
406
        ///////////////////////////////////////
407
        //When buf is ready from VCOMC
408
        if(vcom_choose == PORT_VCOMC_INDEX)
409
        {
410
            if(VCOMC_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMCIndex >= 64)
411
            {
412
413
                vcom_choose = getPriority(vcom_choose, vcom_priority, MAX_VCOM_PORTS); //Calculate next port to send
414
                if(vcom_choose > 3)
415
                {
416
                    asm("nop");
417
                    asm("nop");
418
                    asm("nop");
419
                    asm("nop");
420
                }
421
422
                writtenStatus = true;//Say a wrote has been made
423
                //Send buffer to VCOM
424
                MCOM_sendframe(bufferC, VCOMCIndex, PORT_VCOMC_INDEX);
425
                VCOMCIndex = 0; //reset index buffer
426
                VCOMC_counter = 0; //reset counter
427
            }
428
        }
429
        
430
        
431
        ///////////////////////////////////////
432
        //When buf is ready from VCOMD
433
        if(vcom_choose == PORT_VCOMD_INDEX)
434
        {
435
            if(VCOMD_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMDIndex >= 64)
436
            {
437
438
                vcom_choose = getPriority(vcom_choose, vcom_priority, MAX_VCOM_PORTS); //Calculate next port to send
439
                if(vcom_choose > 3)
440
                {
441
                    asm("nop");
442
                    asm("nop");
443
                    asm("nop");
444
                    asm("nop");
445
                }
446
447
                writtenStatus = true; //Say a wrote has been made
448
                //Send buffer to VCOM
449
                MCOM_sendframe(bufferD, VCOMDIndex, PORT_VCOMD_INDEX);
450
                VCOMDIndex = 0; //reset index buffer
451
                VCOMD_counter = 0; //reset counter
452
            }
453
        }
454
        
455
        ///////////////////////////////////////////////////////////
456
        //Priority check
457
        
458
        //Check if buffer is empty, then put port at lowest priority !
459
        
460
        if(VCOMAIndex == 0) //no buffer ?
461
        {
462
            vcom_priority[PORT_VCOMA_INDEX] = 0; //no priority
463
        }
464
        
465
        
466
        if(VCOMBIndex == 0) //no buffer ?
467
        {
468
            vcom_priority[PORT_VCOMB_INDEX] = 0; //no priority
469
        }
470
        
471
        
472
        if(VCOMCIndex == 0) //no buffer ?
473
        {
474
            vcom_priority[PORT_VCOMC_INDEX] = 0; //no priority
475
        }
476
        
477
        
478
        if(VCOMDIndex == 0) //no buffer ?
479
        {
480
            vcom_priority[PORT_VCOMD_INDEX] = 0; //no priority
481
        }
482
        
483
        
484
    }
485
    
486
    
487
        
488
    return 0;
489
}
490
491
492
493
494
///////////////////////////////////////////////////////////
495
//Functions / macros
496
497
//Send a frame from virtual port to master port
498
499
void MCOM_sendframe(uint8_t *data, uint8_t n, uint8_t port)
500
{
501
    //////////////////////////
502
    //Send frame
503
    
504
    TX_WRITE(0x02); //STX
505
    TX_WRITE(port + CESAR_SHIFT); //Which virtual port called master port ?
506
    TX_WRITE(FRAME_ADDR_1); //ADDR
507
    TX_WRITE(FRAME_ADDR_2); //ADDR
508
    
509
    for(uint8_t i = 0; i < n; i++) //DATA
510
        TX_WRITE(data[i]);
511
    
512
    TX_WRITE(LF_CHAR); //End of frame
513
    TX_WRITE(CR_CHAR); //End of frame
514
    //////////////////////////
515
}
516
517
//////////////////////////////////////////////////////////////////////////////////////////
518
//Send a frame from master port to virtual port (that calculate whose port to send ?)
519
520
void VCOM_sendframe(uint8_t *data, uint8_t n)
521
{
522
    uint16_t addrFunctions[] = {&txWriteA, &txWriteB, &txWriteC, &txWriteD }; //list of available functions addresses
523
    void (*localTxWrite)(); //function pointer
524
525
    ////////////////////////////////
526
    //To debugger read section
527
    
528
    
529
    
530
    for(int i = 0; i < 256; i++)
531
        global_debugBuffer[i] = data[i];
532
    
533
    if(global_n == 0x02)
534
    {
535
        asm("nop");
536
    }
537
    if(global_debugBuffer[1] == 0x03)
538
    {
539
        asm("nop");
540
    }
541
    ////////////////////////////////
542
    
543
    //At first, check if first byte is the start of text
544
    if(data[0] == STX)
545
    {
546
        if(data[2] == FRAME_ADDR_1 && data[3] == FRAME_ADDR_2) //check if we have the MUX address identifier
547
        {    
548
            if(data[n-1] == CR_CHAR) //check the end of text (second byte)
549
            {
550
                if(data[n-2] == LF_CHAR) //check the end of text (first byte)
551
                {
552
                    data[1]-=CESAR_SHIFT; //convert port index to buffer equivalent
553
                    localTxWrite = addrFunctions[(data[1] < 3) ? data[1] : 3 ]; //data[3]
554
                    for(int i = 4; i < n-2; i++) //send frame without (STX + FRAME_ADDR_B1 + FRAME_ADDR_B2 + LF_CHAR + CR_CHAR)
555
                    {
556
                        localTxWrite(data[i]);
557
                    }
558
                    
559
                }
560
            }
561
        }
562
    }
563
}
564
565
566
567
568
//////////////////////////////////////////////////////////////////////////////////////////
569
//Get VCOM port priority to avoid filling hardware buffer and lost data...
570
571
uint8_t getPriority(uint8_t chosen_com, uint8_t *ports_list, uint8_t n)
572
{
573
    uint8_t i = 0; //a little bit useful for timing
574
    
575
    for(i = 0; i < n; i++) //at first increment priority
576
        ports_list[i]++;
577
    
578
    ports_list[chosen_com] = 0; //reset priority on this port
579
    
580
    chosen_com = 0; //load first port
581
    for(i = 1; i < n; i++) //calculate priority
582
    {
583
        if(ports_list[i] > ports_list[chosen_com]) //priority level larger than actual port ?
584
            chosen_com = i; //then choose this port
585
    }
586
        
587
    
588
    
589
    return chosen_com; //port result according to priority
590
}
591
592
593
594
595
void bootSequence(void)
596
{
597
    debugLedsTest();
598
}
599
600
601
602
603
/**
604
 <p><b>void debugLedsTest(void)</b></p>
605
 <p><b>Debug leds test sequence</b></p>
606
 */
607
void debugLedsTest(void)
608
{
609
610
    PORTA.OUT = 1;
611
    for(int i = 0; i < 6; i++)
612
    {
613
        PORTA.OUT <<= 1;
614
        _delay_ms(125);
615
    }
616
    PORTA.OUT = 0;
617
}
618
619
/**
620
 <p><b>void senseDebugLeds(void)</b></p>
621
 <p><b>Call this to update leds status</b></p>
622
 */
623
void senseDebugLeds(bool *hasWritten, bool *hasRead)
624
{
625
    
626
627
    
628
    ///////////////////////////
629
    //Check Master Port
630
    if(*hasWritten)
631
    {
632
        PORTA.OUT |= 0x20;
633
        *hasWritten = false;
634
    }
635
    else
636
        PORTA.OUT &= ~(0x20);
637
    
638
    if(hasRead[PORT_MCOM_INDEX])
639
    {
640
        PORTA.OUT |= 0x10;
641
        hasRead[PORT_MCOM_INDEX] = false;
642
    }
643
    else
644
        PORTA.OUT &= ~(0x10);
645
    
646
    ///////////////////////////
647
    //Check VCOMA
648
    if(hasRead[PORT_VCOMA_INDEX])
649
    {
650
        PORTA.OUT |= 0x01;
651
        hasRead[PORT_VCOMA_INDEX] = false;
652
    }
653
    else
654
        PORTA.OUT &= ~(0x01);
655
    
656
    ///////////////////////////
657
    //Check VCOMB
658
    if(hasRead[PORT_VCOMB_INDEX])
659
    {
660
        PORTA.OUT |= 0x02;
661
        hasRead[PORT_VCOMB_INDEX] = false;
662
    }
663
    else
664
        PORTA.OUT &= ~(0x02);
665
    
666
    ///////////////////////////
667
    //Check VCOMC
668
    if(hasRead[PORT_VCOMC_INDEX])
669
    {
670
        PORTA.OUT |= 0x04;
671
        hasRead[PORT_VCOMC_INDEX] = false;
672
    }
673
    else
674
        PORTA.OUT &= ~(0x04);
675
    
676
    
677
    ///////////////////////////
678
    //Check VCOMD
679
    if(hasRead[PORT_VCOMD_INDEX])
680
    {
681
        PORTA.OUT |= 0x08;
682
        hasRead[PORT_VCOMD_INDEX] = false;
683
    }
684
    else
685
        PORTA.OUT &= ~(0x08);
686
}
687
688
689
690
691
692
693