Statistiques
| Branche: | Révision:

root / Version 2.0 / RS232_MUX.X / main.c @ 8d73eb8a

Historique | Voir | Annoter | Télécharger (32,431 ko)

1 8d73eb8a Enzo Niro
/*
2
 * File:   main.c
3
 * Author: eniro
4
 * Version : 2.0
5
 *
6
 * Created on March 25, 2024, 3:51 PM
7
 */
8
9
10
11
/*
12
 
13
 TODO LIST :
14
 *  
15
 */
16
17
#define F_CPU 24000000UL
18
19
#include <xc.h>
20
#include <stdio.h>
21
#include <string.h>
22
#include <math.h>
23
#include <stdlib.h>
24
#include <util/delay.h>
25
#include <avr/interrupt.h>
26
#include <avr/eeprom.h>
27
28
#include "hardware_uart.h"
29
#include "hardware_timer.h"
30
#include "hardware_TL16C754C.h"
31
#include "hardware_config.h"
32
#include "frame_definitions.h"
33
#include "parameters.h"
34
#include "pins.h"
35
36
//USART setup
37
38
//To calculate BAUD value register -> BAUD = 64*FCLK/(16*FBAUDS)
39
#define UART_BAUD_VALUE     833 // 10000 is equivalent as 9600 bauds (on 24MHz clock) according to datasheet
40
#define USART0_REG          0x3 
41
#define BOOT_MSG            "RS232-MUX\r\n"
42
43
44
45
//OSC. setup
46
#define FREQSEL     0x9
47
#define _FREQSEL_REG_WR     ((FREQSEL) << 2)
48
#define _USART0_REG_WR      (USART0_REG & 0x7)
49
50
51
52
53
54
55
enum portIndex {
56
    PORT_VCOMA_INDEX = 0,
57
    PORT_VCOMB_INDEX,
58
    PORT_VCOMC_INDEX,
59
    PORT_VCOMD_INDEX,
60
    PORT_MCOM_INDEX,
61
};
62
63
64
//////////////////////////////////////////////////////////////
65
//Prototypes
66
67
void bootSequence(void);
68
void setRAMCfg(cfgPort *cfg, uint8_t *localBuffer);
69
void MCOM_scanframe(uint8_t *data, uint8_t n, cfgPort *localPort);
70
void MCOM_sendframe(uint8_t *data, uint8_t n, uint8_t port);
71
void VCOM_sendframe(uint8_t *data, uint8_t n);
72
void senseDebugLeds(bool *hasWritten, bool *hasRead);
73
void readCFG(bool EEPROM_read, cfgPort *localPort);
74
bool stringComp(uint8_t *str1, uint8_t *str2, uint8_t n, uint8_t m);
75
#define WATCHDOG_RESET      asm("WDR") //reset watchdog counter
76
77
78
79
//////////////////////////////////////////////////////////////////////////////
80
//Little Keep save old configuration accessible everywhere (Not good as it is)
81
cfgPort OLD_CFG[4];
82
///////////////////////////
83
84
85
86
87
#ifdef USE_PORT_1 //USART3
88
#define INIT_PORT(w,x,y,z)               initPort1(w,x,y,z)
89
#define TX_WRITE(x)                     txWrite1(x)
90
#define RX_READ                         rxRead1()
91
#define PORT_AVAILABLE                  portAvailable1()
92
#else
93
#ifdef USE_PORT_2 // USART1
94
#define INIT_PORT(w,x,y,z)              initPort2(w,x,y,z)
95
#define TX_WRITE(x)                     txWrite2(x)
96
#define RX_READ                         rxRead2()
97
#define PORT_AVAILABLE                  portAvailable2()
98
#else
99
#ifdef USE_PORT_3 //USART4
100
#define INIT_PORT(w,x,y,z)               initPort3(w,x,y,z)
101
#define TX_WRITE(x)                     txWrite3(x)
102
#define RX_READ                         rxRead3()
103
#define PORT_AVAILABLE                  portAvailable3()
104
#else
105
#ifdef USE_PORT_4 //USART2
106
#define INIT_PORT(w,x,y,z)               initPort4(w,x,y,z)
107
#define TX_WRITE(x)                     txWrite4(x)
108
#define RX_READ                         rxRead4()
109
#define PORT_AVAILABLE                  portAvailable4()
110
#else
111
#error "Please choose an uart port..."
112
#endif
113
#endif
114
#endif
115
#endif
116
117
118
#define DEBUG_LED   0x4
119
120
121
int main(void) {
122
    
123
    cfgPort VCOM_cfg[4];
124
125
    uint8_t masterBuffer[64], bufferA[64], bufferB[64], bufferC[64], bufferD[64];
126
    uint8_t VCOMAIndex = 0, VCOMBIndex = 0, VCOMCIndex = 0, VCOMDIndex = 0, MCOMIndex;
127
    uint16_t MCOM_counter = 0;
128
    uint16_t VCOMA_counter = 0;
129
    uint16_t VCOMB_counter = 0;
130
    uint16_t VCOMC_counter = 0;
131
    uint16_t VCOMD_counter = 0;
132
    uint8_t mainLedCounter = 0;
133
    
134
    bool VCOM_can_read[] = {false, false, false, false};
135
    
136
    bool writtenStatus = false; //put write status on master port
137
    bool readStatus[] = {false, false, false, false, false}; // put read status on all ports
138
 
139
    setWait(5000);
140
    
141
    
142
    for(int i = 0; i < 64; i++)
143
    {
144
        bufferA[i] = 0;
145
    }
146
    for(int i = 0; i < 64; i++)
147
    {
148
        bufferB[i] = 0;
149
    }
150
    for(int i = 0; i < 64; i++)
151
    {
152
        bufferC[i] = 0;
153
    }
154
    for(int i = 0; i < 64; i++)
155
    {
156
        bufferD[i] = 0;
157
    }
158
    
159
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, _FREQSEL_REG_WR); //switch to 24 MHz
160
    
161
    //_delay_ms(3000);
162
    
163
    //Enable pins (Port direction)
164
    ADDR_ENABLE;        //Address pins
165
    ENABLE_WR_RD_PINS;  //Read and Write pins
166
    ENABLE_CS_PINS;     //Chip select pins
167
    ENABLE_RESET_PIN;   //Reset pin
168
    
169
    //////////////////////////////////////////////////////////////
170
    //Remember to put high level on cs pins to disable devices...
171
    SETCSA;
172
    SETCSB;
173
    SETCSC;
174
    SETCSD;
175
    //Also don't forget IOR and IOW
176
    SETWR;
177
    SETRD;
178
    //////////////////////////////////////////////////////////////
179
    
180
    
181
    ////////////////////////////////////////
182
    //init TL16C IC
183
    SETRST; 
184
    //_delay_ms(10);
185
    setWait(100);
186
    CLRRST;
187
    setWait(5);
188
    ////////////////////////////////////////   
189
    
190
    //Init virtual COM ports
191
    setWait(20000);
192
    
193
    //Debug
194
    //char chrDebug[50];
195
    //sprintf(chrDebug, "%x %x %x %x %x %x %x %x\r\n", eeprom_read_byte(0),eeprom_read_byte(1),eeprom_read_byte(2),eeprom_read_byte(3),eeprom_read_byte(4),eeprom_read_byte(5),eeprom_read_byte(6),eeprom_read_byte(7));
196
    
197
    
198
    
199
    getEEPROMCfg(); //at first read EEPROM configuration
200
    readConfiguration(&VCOM_cfg[PORT_VCOMA_INDEX], PORT_VCOMA_INDEX); //Then read configuration for VCOMA
201
    readConfiguration(&VCOM_cfg[PORT_VCOMB_INDEX], PORT_VCOMB_INDEX); //Then read configuration for VCOMB
202
    readConfiguration(&VCOM_cfg[PORT_VCOMC_INDEX], PORT_VCOMC_INDEX); //Then read configuration for VCOMC
203
    readConfiguration(&VCOM_cfg[PORT_VCOMD_INDEX], PORT_VCOMD_INDEX); //Then read configuration for VCOMD
204
    
205
    //Read for old cfg (in case we want to read EEPROM...)
206
    readConfiguration(&OLD_CFG[PORT_VCOMA_INDEX], PORT_VCOMA_INDEX); //Then read configuration for VCOMA
207
    readConfiguration(&OLD_CFG[PORT_VCOMB_INDEX], PORT_VCOMB_INDEX); //Then read configuration for VCOMB
208
    readConfiguration(&OLD_CFG[PORT_VCOMC_INDEX], PORT_VCOMC_INDEX); //Then read configuration for VCOMC
209
    readConfiguration(&OLD_CFG[PORT_VCOMD_INDEX], PORT_VCOMD_INDEX); //Then read configuration for VCOMD
210
    
211
    //Init Virtual Ports
212
    initPortA(VCOM_cfg[PORT_VCOMA_INDEX].baud, VCOM_cfg[PORT_VCOMA_INDEX].dataByte, VCOM_cfg[PORT_VCOMA_INDEX].parity, VCOM_cfg[PORT_VCOMA_INDEX].stopBit);
213
    initPortB(VCOM_cfg[PORT_VCOMB_INDEX].baud, VCOM_cfg[PORT_VCOMB_INDEX].dataByte, VCOM_cfg[PORT_VCOMB_INDEX].parity, VCOM_cfg[PORT_VCOMB_INDEX].stopBit);
214
    initPortC(VCOM_cfg[PORT_VCOMC_INDEX].baud, VCOM_cfg[PORT_VCOMC_INDEX].dataByte, VCOM_cfg[PORT_VCOMC_INDEX].parity, VCOM_cfg[PORT_VCOMC_INDEX].stopBit);
215
    initPortD(VCOM_cfg[PORT_VCOMD_INDEX].baud, VCOM_cfg[PORT_VCOMD_INDEX].dataByte, VCOM_cfg[PORT_VCOMD_INDEX].parity, VCOM_cfg[PORT_VCOMD_INDEX].stopBit);
216
    
217
    
218
    
219
    //Master Port
220
    INIT_PORT(UART_BAUD_VALUE, F8BIT_MODE, ONE_STOPBIT, AVR32_NO_PARITY);
221
    
222
    //Boot led
223
    PORTC.DIR |= DEBUG_LED;
224
    SET_DEBUG_LED;
225
    setWait(500);
226
    CLR_DEBUG_LED;
227
    /*for(int i = 0; i < 25; i++)
228
    {
229
        TX_WRITE(chrDebug[i]);
230
    }*/
231
    
232
    timerInit(60000); //10 ms interrupt
233
    sei(); //never forget to enable global interrupt mask !
234
    
235
    PORTA.DIR = 0x3F;
236
    
237
    
238
    
239
    bootSequence();
240
    
241
    
242
    
243
    while(1)
244
    {
245
        //WDT refresh (avoid program freeze when on crash...)
246
        WATCHDOG_RESET;
247
        
248
        ////////////////////////////////////////////////////////
249
        //Read UART A
250
        
251
        
252
        if(portA_available()) //Check if one byte available
253
        {
254
            /////////////////////////////////////////
255
            //Frame check
256
            
257
            VCOM_can_read[PORT_VCOMA_INDEX] = true;
258
            if(getParitySetA()) //if parity set
259
            {
260
                if(getErrorStatusA()) //if parity failed (or stop bit also)
261
                {
262
                    VCOM_can_read[PORT_VCOMA_INDEX] = false; 
263
                }
264
            }
265
            
266
            /////////////////////////////////////////
267
            
268
            if(VCOM_can_read[PORT_VCOMA_INDEX]) //if we can read according to parity
269
            {
270
                readStatus[PORT_VCOMA_INDEX] = true;
271
                bufferA[VCOMAIndex] = rxReadA(); 
272
                VCOMAIndex++; 
273
                VCOMA_counter = 0; //for frame timeout
274
            }
275
            else //if read failed
276
            {
277
                rxReadA(); //flush serial
278
            }     
279
        }
280
        
281
        ////////////////////////////////////////////////////////
282
        //Read UART B
283
        
284
        
285
        if(portB_available()) //Check if one byte available
286
        {
287
            /////////////////////////////////////////
288
            //Frame check
289
            
290
            VCOM_can_read[PORT_VCOMB_INDEX] = true;
291
            if(getParitySetB()) //if parity set
292
            {
293
                if(getErrorStatusB()) //if parity failed (or stop bit also)
294
                {
295
                    VCOM_can_read[PORT_VCOMB_INDEX] = false; 
296
                }
297
            }
298
            
299
            /////////////////////////////////////////
300
            
301
            
302
            
303
            if(VCOM_can_read[PORT_VCOMB_INDEX]) //if we can read according to parity
304
            {
305
                readStatus[PORT_VCOMB_INDEX] = true;
306
                bufferB[VCOMBIndex] = rxReadB();
307
                VCOMBIndex++; 
308
                //if(VCOMBIndex > 64)
309
                //    VCOMBIndex = 0;
310
                VCOMB_counter = 0; //for frame timeout  
311
            }
312
            else //if read failed
313
            {
314
                rxReadB(); //flush serial
315
            } 
316
        }
317
        
318
        
319
        ////////////////////////////////////////////////////////
320
        //Read UART C
321
        
322
        
323
        if(portC_available()) //Check if one byte available
324
        {
325
            /////////////////////////////////////////
326
            //Frame check
327
            
328
            VCOM_can_read[PORT_VCOMC_INDEX] = true;
329
            if(getParitySetC()) //if parity set
330
            {
331
                if(getErrorStatusC()) //if parity failed (or stop bit also)
332
                {
333
                    VCOM_can_read[PORT_VCOMC_INDEX] = false; 
334
                }
335
            }
336
            
337
            /////////////////////////////////////////
338
            
339
            
340
            
341
            if(VCOM_can_read[PORT_VCOMC_INDEX]) //if we can read according to parity
342
            {
343
                readStatus[PORT_VCOMC_INDEX] = true;
344
                bufferC[VCOMCIndex] = rxReadC();
345
                VCOMCIndex++; 
346
                //if(VCOMBIndex > 64)
347
                //    VCOMBIndex = 0;
348
                VCOMC_counter = 0; //for frame timeout  
349
            }
350
            else //if read failed
351
            {
352
                rxReadC(); //flush serial
353
            } 
354
        }
355
        
356
        
357
        
358
        ////////////////////////////////////////////////////////
359
        //Read UART D
360
        
361
        
362
        if(portD_available()) //Check if one byte available
363
        {
364
            /////////////////////////////////////////
365
            //Frame check
366
            
367
            VCOM_can_read[PORT_VCOMD_INDEX] = true;
368
            if(getParitySetD()) //if parity set
369
            {
370
                if(getErrorStatusD()) //if parity failed (or stop bit also)
371
                {
372
                    VCOM_can_read[PORT_VCOMD_INDEX] = false; 
373
                }
374
            }
375
            
376
            /////////////////////////////////////////
377
            
378
            
379
            
380
            if(VCOM_can_read[PORT_VCOMD_INDEX]) //if we can read according to parity
381
            {
382
                readStatus[PORT_VCOMD_INDEX] = true;
383
                bufferD[VCOMDIndex] = rxReadD();
384
                VCOMDIndex++; 
385
                //if(VCOMBIndex > 64)
386
                //    VCOMBIndex = 0;
387
                VCOMD_counter = 0; //for frame timeout  
388
            }
389
            else //if read failed
390
            {
391
                rxReadD(); //flush serial
392
            } 
393
        }
394
        
395
        
396
        ////////////////////////////////////////////////////////
397
        //Read UART Master
398
        
399
        
400
        if(PORT_AVAILABLE > 0) //check if we have bytes to read
401
        {
402
            readStatus[PORT_MCOM_INDEX] = true;
403
            masterBuffer[MCOMIndex] = RX_READ; //store byte into buffer
404
            MCOMIndex++; //increment to next byte
405
            //if(MCOMIndex > 64)
406
            //    MCOMIndex = 0;
407
            MCOM_counter = 0; //refresh timeout counter
408
        }
409
        /*else
410
        {
411
            readStatus[PORT_MCOM_INDEX] = false; //To prevent the bug on uC (Silicon cause ?)
412
        }*/
413
        
414
        
415
        
416
417
        //Timed process (for leds, etc...)
418
        if(getTimerFlag())
419
        {
420
            if(mainLedCounter > 240)
421
            {
422
                SET_DEBUG_LED;
423
            }
424
            else
425
                CLR_DEBUG_LED;
426
            
427
            mainLedCounter++;
428
            
429
            /////////////////////////////////////////////////////////
430
            //Timeout process
431
432
            //For master port
433
            if(MCOMIndex > 0)
434
                MCOM_counter++;
435
436
            //For virtual port 1
437
            if(VCOMAIndex > 0)
438
                VCOMA_counter++;
439
440
            //For virtual port 2
441
            if(VCOMBIndex > 0)
442
                VCOMB_counter++;
443
444
            //For virtual port 3
445
            if(VCOMCIndex > 0)
446
                VCOMC_counter++;
447
448
            //For virtual port 4
449
            if(VCOMDIndex > 0)
450
                VCOMD_counter++;
451
            
452
            
453
            senseDebugLeds(&writtenStatus, readStatus);
454
            clearTimerFlag();
455
        }
456
        
457
        
458
            
459
        
460
        
461
        ///////////////////////////////////////
462
        //When buf is ready from master
463
        if(MCOM_counter > SERIAL_PORT_TIMEOUT_COUNT || MCOMIndex >= 64)
464
        {         
465
            //Send buffer to VCOM
466
            if(masterBuffer[1] == MASTER_ID) //check if frame is destinated to the MUX232
467
            {
468
                MCOM_scanframe(masterBuffer, MCOMIndex, VCOM_cfg);
469
            }
470
            else //otherwise send it through a VCOM
471
            {
472
                VCOM_sendframe(masterBuffer, MCOMIndex);
473
            }
474
            
475
            MCOMIndex = 0; //reset index buffer
476
            MCOM_counter = 0; //reset counter
477
        }
478
        
479
        
480
        ///////////////////////////////////////
481
        //When buf is ready from VCOMA
482
483
        if(VCOMA_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMAIndex >= 64)
484
        {
485
            writtenStatus = true;//Say a wrote has been made
486
            //Send buffer to VCOM
487
            MCOM_sendframe(bufferA, VCOMAIndex, PORT_VCOMA_INDEX);
488
            VCOMAIndex = 0; //reset index buffer
489
            VCOMA_counter = 0; //reset counter
490
        }
491
        
492
        
493
        
494
        ///////////////////////////////////////
495
        //When buf is ready from VCOMB
496
497
        if(VCOMB_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMBIndex >= 64)
498
        {
499
            writtenStatus = true;//Say a wrote has been made
500
            //Send buffer to VCOM
501
            MCOM_sendframe(bufferB, VCOMBIndex, PORT_VCOMB_INDEX);
502
            VCOMBIndex = 0; //reset index buffer
503
            VCOMB_counter = 0; //reset counter
504
        }
505
        
506
        
507
        ///////////////////////////////////////
508
        //When buf is ready from VCOMC
509
        if(VCOMC_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMCIndex >= 64)
510
        {
511
            writtenStatus = true;//Say a wrote has been made
512
            //Send buffer to VCOM
513
            MCOM_sendframe(bufferC, VCOMCIndex, PORT_VCOMC_INDEX);
514
            VCOMCIndex = 0; //reset index buffer
515
            VCOMC_counter = 0; //reset counter
516
        }
517
518
        
519
        
520
521
        if(VCOMD_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMDIndex >= 64)
522
        {
523
524
            writtenStatus = true; //Say a wrote has been made
525
            //Send buffer to VCOM
526
            MCOM_sendframe(bufferD, VCOMDIndex, PORT_VCOMD_INDEX);
527
            VCOMDIndex = 0; //reset index buffer
528
            VCOMD_counter = 0; //reset counter
529
        }
530
        
531
        
532
    }
533
    
534
    
535
    return 0;
536
}
537
538
539
540
541
///////////////////////////////////////////////////////////
542
//Functions / macros
543
//bool EEPROM_read -> true read from EEPROM, false -> read from RAM
544
//cfgPort *cfg -> configuration where values must be read
545
void readCFG(bool EEPROM_read, cfgPort *localPort)
546
{
547
    cfgPort *debugPort;
548
549
    const uint8_t *dispBaud[] = {"9600", "19200", "38400"}; 
550
    const uint8_t dispParity[] = {'N', 'E', 'O'}; //The Matrix has you...
551
    const uint8_t dispData[] = {'5', '6', '7', '8'};
552
    const uint8_t dispBit[] = {'1', '2'};
553
    char msg[30]; //23 characters max
554
    
555
       
556
    //Read EEPROM configuration or RAM ?
557
    //if(EEPROM_read)
558
    //    getEEPROMCfg();
559
    
560
        
561
    
562
    if(!EEPROM_read) //Read RAM CFG ?
563
        debugPort = &localPort[PORT_VCOMA_INDEX];
564
    else
565
        debugPort = &OLD_CFG[PORT_VCOMA_INDEX];
566
        
567
        //readConfiguration(debugPort, PORT_VCOMA_INDEX); //or just get CFG read from EEPROM
568
    //Disp CFGRead bytes and display directly CFG
569
    for(int i = 0; i < 30; i++)
570
    {
571
        msg[i] = 0;
572
    }
573
    sprintf(msg, "%c%c%c%cVCOMA B%s F%c%c%c\r\n", 
574
            STX, 
575
            MASTER_ID, 
576
            FRAME_ADDR_1, 
577
            FRAME_ADDR_2, 
578
            dispBaud[debugPort->baud], 
579
            dispData[debugPort->dataByte], 
580
            dispParity[debugPort->parity], 
581
            dispBit[debugPort->stopBit]
582
            );
583
    for(uint8_t i = 0; i < 22; i++)
584
        TX_WRITE(msg[i]); //Display string
585
    
586
    if(!EEPROM_read) //Read RAM CFG ?
587
        debugPort = &localPort[PORT_VCOMB_INDEX];
588
    else
589
        debugPort = &OLD_CFG[PORT_VCOMB_INDEX];
590
        //readConfiguration(debugPort, PORT_VCOMB_INDEX); //or just get CFG read from EEPROM
591
    //Disp CFGRead bytes and display directly CFG
592
    for(int i = 0; i < 30; i++)
593
    {
594
        msg[i] = 0;
595
    }
596
    
597
    sprintf(msg, "%c%c%c%cVCOMB B%s F%c%c%c\r\n", 
598
            STX, 
599
            MASTER_ID, 
600
            FRAME_ADDR_1, 
601
            FRAME_ADDR_2, 
602
            dispBaud[debugPort->baud], 
603
            dispData[debugPort->dataByte], 
604
            dispParity[debugPort->parity], 
605
            dispBit[debugPort->stopBit]
606
            );
607
    for(uint8_t i = 0; i < 22; i++)
608
        TX_WRITE(msg[i]); //Display string
609
    
610
    if(!EEPROM_read) //Read RAM CFG ?
611
        debugPort = &localPort[PORT_VCOMC_INDEX];
612
    else
613
        debugPort = &OLD_CFG[PORT_VCOMC_INDEX];
614
        //readConfiguration(debugPort, PORT_VCOMC_INDEX); //or just get CFG read from EEPROM
615
    //Disp CFGRead bytes and display directly CFG
616
    for(int i = 0; i < 30; i++)
617
    {
618
        msg[i] = 0;
619
    }
620
    sprintf(msg, "%c%c%c%cVCOMC B%s F%c%c%c\r\n", 
621
            STX, 
622
            MASTER_ID, 
623
            FRAME_ADDR_1, 
624
            FRAME_ADDR_2, 
625
            dispBaud[debugPort->baud],
626
            dispData[debugPort->dataByte], 
627
            dispParity[debugPort->parity], 
628
            dispBit[debugPort->stopBit]
629
            );
630
    for(uint8_t i = 0; i < 22; i++)
631
        TX_WRITE(msg[i]); //Display string
632
    
633
    if(!EEPROM_read) //Read RAM CFG ?
634
        debugPort = &localPort[PORT_VCOMD_INDEX];
635
    else
636
        debugPort = &OLD_CFG[PORT_VCOMD_INDEX];
637
        //readConfiguration(debugPort, PORT_VCOMD_INDEX); //or just get CFG read from EEPROM
638
    //Disp CFGRead bytes and display directly CFG
639
    for(int i = 0; i < 30; i++)
640
    {
641
        msg[i] = 0;
642
    }
643
    sprintf(msg, "%c%c%c%cVCOMD B%s F%c%c%c\r\n", 
644
            STX, 
645
            MASTER_ID, 
646
            FRAME_ADDR_1, 
647
            FRAME_ADDR_2, 
648
            dispBaud[debugPort->baud], 
649
            dispData[debugPort->dataByte], 
650
            dispParity[debugPort->parity], 
651
            dispBit[debugPort->stopBit]
652
            );
653
    for(uint8_t i = 0; i < 22; i++)
654
        TX_WRITE(msg[i]); //Display string
655
}
656
657
658
//Set RAM Cfg that we must apply it to the EEPROM !
659
//cfgPort *cfg -> configuration where values must be applied
660
//uint8_t *localBuffer -> frame command structured by "BxxxxxFxxxCx" (see documentation)
661
void setRAMCfg(cfgPort *cfg, uint8_t *localBuffer)
662
{
663
    //Set default CFG
664
    uint8_t localBaudsCfg = ADDR_BAUD_9600, localDataCfg = ADDR_DATA_F8; 
665
    uint8_t localParityCfg = ADDR_PARITY_NONE, localSBCfg = ADDR_STOP_ONE;
666
    uint8_t localVCOMIndex;
667
    uint8_t localIndex;
668
    uint8_t i;
669
    
670
    ////////////////////////////////////////////////////////
671
    //VCOM CONFIGURATION
672
673
    //Be sure our first character is B (so we can estimate that frame is good enough)
674
    if (localBuffer[MAX232_B_STR_INDEX] == MAX232_B_STR_CHAR) 
675
    {
676
        localIndex = MAX232_B_STR_INDEX;
677
        i = 0;
678
        //Calculate number of bytes between B and F char into frame (9600 bauds or 19200/38400 bauds for example)
679
        while (localBuffer[localIndex] != MAX232_F_STR_CHAR) 
680
        {
681
            i++;
682
            localIndex++;
683
        }
684
        if (i < 6) //number of char = 4 ? ("9600")
685
        {
686
687
            //////////////////////////////////////////
688
            //At first set bauds speed
689
            if (localBuffer[MAX232_B_STR_INDEX + 1] == '9' && localBuffer[MAX232_B_STR_INDEX + 2] == '6' &&
690
                localBuffer[MAX232_B_STR_INDEX + 3] == '0' && localBuffer[MAX232_B_STR_INDEX + 4] == '0') 
691
            {
692
                //Put CFG into 9600 bauds
693
                localBaudsCfg = ADDR_BAUD_9600;
694
            }
695
            //////////////////////////////////////////
696
            //Set Data bits
697
            localDataCfg = localBuffer[MAX232_B_STR_INDEX + 6] - '5'; // Shift to 0 because ADDR_DATA_F5 = 0, ADDR_DATA_F6 = 1, ect...
698
            //We have already localDataCfg as ADDR_PARITY_NONE (keep aat this value if it equals to 'N')
699
            //localParityCfg = (localBuffer[MAX232_B_STR_INDEX + 7] == 'N') ? ADDR_PARITY_NONE : localDataCfg;
700
            //Does it equals to ODD ?
701
            localParityCfg = (localBuffer[MAX232_B_STR_INDEX + 7] == 'O') ? ADDR_PARITY_ODD : localParityCfg;
702
            //or EVEN ?
703
            localParityCfg = (localBuffer[MAX232_B_STR_INDEX + 7] == 'E') ? ADDR_PARITY_EVEN : localParityCfg;
704
            //Read (localBuffer[MAX232_B_STR_INDEX + 8] for stop bits -> 1/2
705
            localSBCfg = (localBuffer[MAX232_B_STR_INDEX + 8] == '2'); //Return condition state only...
706
            //Read (localBuffer[MAX232_B_STR_INDEX + 10] VCOM -> A/B/C/D
707
            localVCOMIndex = localBuffer[MAX232_B_STR_INDEX + 10] - CESAR_SHIFT;
708
        } 
709
        else //number of char = 5 ? ("19200"/"38400")
710
        {
711
            //////////////////////////////////////////
712
            //At first set bauds speed
713
714
            if (localBuffer[MAX232_B_STR_INDEX + 1] == '1' && localBuffer[MAX232_B_STR_INDEX + 2] == '9' &&
715
                localBuffer[MAX232_B_STR_INDEX + 3] == '2' && localBuffer[MAX232_B_STR_INDEX + 4] == '0' &&
716
                localBuffer[MAX232_B_STR_INDEX + 5] == '0') 
717
            {
718
                //Put CFG into 19200 bauds
719
                localBaudsCfg = ADDR_BAUD_19200;
720
            }
721
722
            if (localBuffer[MAX232_B_STR_INDEX + 1] == '3' && localBuffer[MAX232_B_STR_INDEX + 2] == '8' &&
723
                localBuffer[MAX232_B_STR_INDEX + 3] == '4' && localBuffer[MAX232_B_STR_INDEX + 4] == '0' &&
724
                localBuffer[MAX232_B_STR_INDEX + 5] == '0') 
725
            {
726
                //Put CFG into 38400 bauds
727
                localBaudsCfg = ADDR_BAUD_38400;
728
            }
729
730
            //////////////////////////////////////////
731
732
            //Set Data bits
733
            localDataCfg = localBuffer[MAX232_B_STR_INDEX + 7] - '5'; // Shift to 0 because ADDR_DATA_F5 = 0, ADDR_DATA_F6 = 1, ect...
734
            //We have already localDataCfg as ADDR_PARITY_NONE (keep aat this value if it equals to 'N')
735
            //localParityCfg = (localBuffer[MAX232_B_STR_INDEX + 7] == 'N') ? ADDR_PARITY_NONE : localDataCfg;
736
            //Does it equals to ODD ?
737
            localParityCfg = (localBuffer[MAX232_B_STR_INDEX + 8] == 'O') ? ADDR_PARITY_ODD : localParityCfg;
738
            //or EVEN ?
739
            localParityCfg = (localBuffer[MAX232_B_STR_INDEX + 8] == 'E') ? ADDR_PARITY_EVEN : localParityCfg;
740
            //Read (localBuffer[MAX232_B_STR_INDEX + 8] for stop bits -> 1/2
741
            localSBCfg = (localBuffer[MAX232_B_STR_INDEX + 9] == '2'); //Return condition state only for stop bits...
742
            //Read (localBuffer[MAX232_B_STR_INDEX + 10] VCOM -> A/B/C/D
743
            localVCOMIndex = localBuffer[MAX232_B_STR_INDEX + 11] - CESAR_SHIFT;
744
            //TX_WRITE('F'); TX_WRITE('D'); TX_WRITE('P'); TX_WRITE(localBuffer[MAX232_B_STR_INDEX + 9]);
745
            //TX_WRITE('F'); TX_WRITE('D'); TX_WRITE('P'); TX_WRITE(localBuffer[MAX232_B_STR_INDEX + 11]);
746
            //TX_WRITE('F'); TX_WRITE('D'); TX_WRITE('P'); TX_WRITE(localParityCfg);
747
        }
748
        //Write into RAM buffer (and prepare for EEPROM writing)
749
        writeConfiguration(&cfg[localVCOMIndex], localBaudsCfg, localParityCfg, localDataCfg, localSBCfg, localVCOMIndex);
750
    }
751
    ////////////////////////////////////////////////////////
752
    
753
}
754
755
756
//Read a frame destinated to the MUX232 itself
757
//uint8_t *data -> frame buffer (with SOF, ADDR, ..., EOF)
758
//uint8_t n -> size of that buffer
759
//cfgPort *localPort -> configuration structure that will be read/written (depend on cmd that inside of *data)
760
void MCOM_scanframe(uint8_t *data, uint8_t n, cfgPort *localPort)
761
{
762
    
763
    uint8_t *localBuffer; //Calculate byte quantity of effective data
764
    uint8_t i;
765
    
766
    
767
    while(localBuffer == NULL)
768
    {
769
        localBuffer = malloc(n-6);
770
        setWait(5);
771
    }
772
    
773
    for(i = 0; i < n-6; i++)
774
        localBuffer[i] = 0;
775
    
776
    //At first, check if first byte is the start of text
777
    if(data[0] == STX)
778
    {
779
        if(data[2] == FRAME_ADDR_1 && data[3] == FRAME_ADDR_2) //check if we have the MUX address identifier
780
        {    
781
            if(data[n-1] == CR_CHAR) //check the end of text (second byte)
782
            {
783
                if(data[n-2] == LF_CHAR) //check the end of text (first byte)
784
                {
785
                    for(i = 0; i < n-6; i++) //regarder la valeur de n
786
                    {
787
                        localBuffer[i] = data[i + 4]; //Get effective data
788
                    }
789
                    //Once data was collected, analysis it
790
                    if(!stringComp(localBuffer, MAX232_WRITE_COMMAND, n-6, MAX232_WRITE_SIZE)) //if the command is Write configuration
791
                    {
792
                        //Save CFG into EEPROM
793
                        setEEPROMCfg();
794
                        TX_WRITE(0x2);
795
                        TX_WRITE(FRAME_ADDR_1);
796
                        TX_WRITE(FRAME_ADDR_2);
797
                        TX_WRITE(MASTER_ID);
798
                        TX_WRITE('W');TX_WRITE('R');
799
                        TX_WRITE('C');TX_WRITE('F');TX_WRITE('G');
800
                        TX_WRITE(LF_CHAR);TX_WRITE(CR_CHAR);
801
                        
802
                        TX_WRITE(0x2);
803
                        TX_WRITE(FRAME_ADDR_1);
804
                        TX_WRITE(FRAME_ADDR_2);
805
                        TX_WRITE(MASTER_ID);
806
                        TX_WRITE('R');TX_WRITE('E');TX_WRITE('B');TX_WRITE('O');TX_WRITE('O');TX_WRITE('T');
807
                        TX_WRITE(LF_CHAR);TX_WRITE(CR_CHAR);
808
                        
809
                        while(1); //Force WDT reboot
810
                    }
811
                    else if(!stringComp(localBuffer, MAX232_READ_RAM_COMMAND, n-6, MAX232_READ_RAM_SIZE)) //is this Read configuration ?
812
                    {
813
                        //Read CFG from RAM
814
                        readCFG(false, localPort);
815
                    }
816
                    else if(!stringComp(localBuffer, MAX232_READ_ROM_COMMAND, n-6, MAX232_READ_ROM_SIZE)) //is this Read configuration ?
817
                    {
818
                        //Read CFG from EEPROM
819
                        readCFG(true, localPort);
820
                    }
821
                    else //otherwise that might be set configuration
822
                    {
823
                        setRAMCfg(localPort, localBuffer);      
824
                        TX_WRITE(0x2);
825
                        TX_WRITE(FRAME_ADDR_1);
826
                        TX_WRITE(FRAME_ADDR_2);
827
                        TX_WRITE(MASTER_ID);
828
                        TX_WRITE('S');TX_WRITE('E');TX_WRITE('T');
829
                        TX_WRITE('C');TX_WRITE('F');TX_WRITE('G');
830
                        TX_WRITE(LF_CHAR);TX_WRITE(CR_CHAR);
831
                    }
832
                }
833
            }
834
        }
835
    }
836
}
837
838
839
840
//Send a frame from virtual port to master port
841
//uint8_t *data -> data buffer read from device
842
//uint8_t n -> size of that buffer
843
//uint8_t port tell which port that come from (0~3)
844
void MCOM_sendframe(uint8_t *data, uint8_t n, uint8_t port)
845
{
846
    //////////////////////////
847
    //Send frame
848
    
849
    TX_WRITE(0x02); //STX
850
    TX_WRITE(port + CESAR_SHIFT); //Which virtual port called master port ?
851
    TX_WRITE(FRAME_ADDR_1); //ADDR
852
    TX_WRITE(FRAME_ADDR_2); //ADDR
853
    
854
    for(uint8_t i = 0; i < n; i++) //DATA
855
        TX_WRITE(data[i]);
856
    
857
    TX_WRITE(LF_CHAR); //End of frame
858
    TX_WRITE(CR_CHAR); //End of frame
859
    //////////////////////////
860
}
861
862
//////////////////////////////////////////////////////////////////////////////////////////
863
//Send a frame from master port to virtual port (that calculate whose port to send ?)
864
//uint8_t *data -> frame buffer (with SOF, ADDR, ..., EOF)
865
//uint8_t n -> size of that buffer
866
void VCOM_sendframe(uint8_t *data, uint8_t n)
867
{
868
    uint16_t addrFunctions[] = {&txWriteA, &txWriteB, &txWriteC, &txWriteD }; //list of available functions addresses
869
    void (*localTxWrite)(); //function pointer
870
871
872
    ////////////////////////////////
873
    
874
    //At first, check if first byte is the start of text
875
    if(data[0] == STX)
876
    {
877
        if(data[2] == FRAME_ADDR_1 && data[3] == FRAME_ADDR_2) //check if we have the MUX address identifier
878
        {    
879
            if(data[n-1] == CR_CHAR) //check the end of text (second byte)
880
            {
881
                if(data[n-2] == LF_CHAR) //check the end of text (first byte)
882
                {
883
                    data[1]-=CESAR_SHIFT; //convert port index to buffer equivalent
884
                    localTxWrite = addrFunctions[(data[1] < 3) ? data[1] : 3 ]; //data[3]
885
                    for(int i = 4; i < n-2; i++) //send frame without (STX + FRAME_ADDR_B1 + FRAME_ADDR_B2 + LF_CHAR + CR_CHAR)
886
                    {
887
                        localTxWrite(data[i]);
888
                    }
889
                    
890
                }
891
            }
892
        }
893
    }
894
}
895
896
897
898
899
900
901
/**
902
 void bootSequence(void)
903
 Display boot message and launch test led sequence
904
 */
905
void bootSequence(void)
906
{
907
    TX_WRITE(STX);
908
    TX_WRITE(MASTER_ID);TX_WRITE(FRAME_ADDR_1);TX_WRITE(FRAME_ADDR_1);
909
    TX_WRITE('B');TX_WRITE('O');TX_WRITE('O');TX_WRITE('T');
910
    TX_WRITE(LF_CHAR);TX_WRITE(CR_CHAR);
911
    debugLedsTest();
912
}
913
914
915
916
917
/**
918
 void debugLedsTest(void)
919
 Debug leds test sequence
920
 */
921
void debugLedsTest(void)
922
{
923
    //All leds are on PORTA -> Bit shifting is adviced
924
    PORTA.OUT = 1;
925
    for(int i = 0; i < 6; i++)
926
    {
927
        PORTA.OUT <<= 1;
928
        _delay_ms(250);
929
    }
930
    PORTA.OUT = 0;
931
}
932
933
/**
934
 void senseDebugLeds(void)
935
 ->Call this to update leds status
936
 * bool *hasWritten -> put written status of write led
937
 * bool *hasWritten -> put read status of read leds port
938
 */
939
void senseDebugLeds(bool *hasWritten, bool *hasRead)
940
{
941
    
942
943
    
944
    ///////////////////////////
945
    //Check Master Port
946
    if(*hasWritten)
947
    {
948
        SET_MASTER_WR_LED;
949
        *hasWritten = false;
950
    }
951
    else
952
        CLR_MASTER_WR_LED;
953
    
954
    if(hasRead[PORT_MCOM_INDEX])
955
    {
956
        SET_MASTER_RD_LED;
957
        hasRead[PORT_MCOM_INDEX] = false;
958
    }
959
    else
960
        CLR_MASTER_RD_LED;
961
    
962
    ///////////////////////////
963
    //Check VCOMA
964
    if(hasRead[PORT_VCOMA_INDEX])
965
    {
966
        SET_VCOMA_RD_LED;
967
        hasRead[PORT_VCOMA_INDEX] = false;
968
    }
969
    else
970
        CLR_VCOMA_RD_LED;
971
    
972
    ///////////////////////////
973
    //Check VCOMB
974
    if(hasRead[PORT_VCOMB_INDEX])
975
    {
976
        SET_VCOMB_RD_LED;
977
        hasRead[PORT_VCOMB_INDEX] = false;
978
    }
979
    else
980
        CLR_VCOMB_RD_LED;
981
    
982
    ///////////////////////////
983
    //Check VCOMC
984
    if(hasRead[PORT_VCOMC_INDEX])
985
    {
986
        SET_VCOMC_RD_LED;
987
        hasRead[PORT_VCOMC_INDEX] = false;
988
    }
989
    else
990
        CLR_VCOMC_RD_LED;
991
    
992
    
993
    ///////////////////////////
994
    //Check VCOMD
995
    if(hasRead[PORT_VCOMD_INDEX])
996
    {
997
        SET_VCOMD_RD_LED;
998
        hasRead[PORT_VCOMD_INDEX] = false;
999
    }
1000
    else
1001
        CLR_VCOMD_RD_LED;
1002
}
1003
1004
1005
//String comparator (better version...)
1006
//uint8_t *str1 -> First string to compare
1007
//uint8_t *str2 -> Second string to compare
1008
//uint8_t n -> Size of first string
1009
//uint8_t m -> Size of second string
1010
bool stringComp(uint8_t *str1, uint8_t *str2, uint8_t n, uint8_t m)
1011
{
1012
    bool result = false;
1013
    
1014
    if(n == m)
1015
    {
1016
        for(int i = 0; i < n; i++)
1017
        {
1018
            //TX_WRITE('A');TX_WRITE(':');TX_WRITE(str1[i]);TX_WRITE(" ");
1019
            //TX_WRITE('B');TX_WRITE(':');TX_WRITE(str2[i]);TX_WRITE("\n");TX_WRITE("\r");
1020
            if(str1[i] != str2[i]) //different string...
1021
                result = true; 
1022
        }
1023
    }
1024
    else
1025
    {
1026
        result = true;
1027
    } 
1028
    return result;
1029
}
1030
1031
1032
1033
1034