Statistiques
| Branche: | Révision:

root / Version 1.9 / RS232_MUX.X / main.c @ 350cdd5d

Historique | Voir | Annoter | Télécharger (31,541 ko)

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