Statistiques
| Branche: | Révision:

root / Version 1.3 / RS232_MUX.X / main.c @ f4f84cf1

Historique | Voir | Annoter | Télécharger (14,634 ko)

1
/*
2
 * File:   main.c
3
 * Author: eniro
4
 * Version : 0.9
5
 *
6
 * Created on March 25, 2024, 3:51 PM
7
 */
8

    
9

    
10

    
11
/*
12
 
13
 TODO LIST :
14
 * 
15
 * 
16
 * Remap all pins !!!
17
 * 
18
 * Select UART1 as master port
19
 * 
20
 * Rename VCOMA/2/3/4 as VCOMA/B/C/D ?
21
 
22
 */
23

    
24
#define F_CPU 24000000UL
25

    
26
#include <xc.h>
27
#include <math.h>
28
#include <stdlib.h>
29
#include <util/delay.h>
30
#include <avr/interrupt.h>
31
#include <avr/eeprom.h>
32

    
33
#include "hardware_uart.h"
34
#include "hardware_timer.h"
35
#include "hardware_TL16C754C.h"
36
#include "hardware_config.h"
37
#include "frame_definitions.h"
38
#include "parameters.h"
39

    
40
//USART setup
41

    
42
//To calculate BAUD value register -> BAUD = 64*FCLK/(16*FBAUDS)
43
#define UART_BAUD_VALUE     833 // 10000 is equivalent as 9600 bauds (on 24MHz clock) according to datasheet
44
#define USART0_REG          0x3 
45
#define BOOT_MSG            "RS232-MUX\r\n"
46

    
47

    
48

    
49
//OSC. setup
50
#define FREQSEL     0x9
51
#define _FREQSEL_REG_WR     ((FREQSEL) << 2)
52
#define _USART0_REG_WR      (USART0_REG & 0x7)
53

    
54

    
55

    
56

    
57

    
58

    
59
enum portIndex {
60
    PORT_VCOMA_INDEX = 0,
61
    PORT_VCOMB_INDEX,
62
    PORT_VCOMC_INDEX,
63
    PORT_VCOMD_INDEX,
64
    PORT_MCOM_INDEX,
65
};
66

    
67

    
68
//////////////////////////////////////////////////////////////
69
//Prototypes
70

    
71
void bootSequence(void);
72
void MCOM_sendframe(uint8_t *data, uint8_t n, uint8_t port);
73
void VCOM_sendframe(uint8_t *data, uint8_t n);
74
void senseDebugLeds(bool *hasWritten, bool *hasRead);
75

    
76
//reset watchdog counter
77
#define WATCHDOG_RESET      asm("WDR")
78

    
79
uint8_t global_debugBuffer[256];
80
uint8_t global_n = 0;
81
uint8_t global_parity;
82

    
83

    
84

    
85

    
86

    
87

    
88
#ifdef USE_PORT_1
89
#define INIT_PORT(w,x,y,z)               initPort1(w,x,y,z)
90
#define TX_WRITE(x)                     txWrite1(x)
91
#define RX_READ                         rxRead1()
92
#define PORT_AVAILABLE                  portAvailable1()
93
#else
94
#ifdef USE_PORT_2
95
#define INIT_PORT(w,x,y,z)               initPort2(w,x,y,z)
96
#define TX_WRITE(x)                     txWrite2(x)
97
#define RX_READ                         rxRead2()
98
#define PORT_AVAILABLE                  portAvailable2()
99
#else
100
#ifdef USE_PORT_3
101
#define INIT_PORT(w,x,y,z)               initPort3(w,x,y,z)
102
#define TX_WRITE(x)                     txWrite3(x)
103
#define RX_READ                         rxRead3()
104
#define PORT_AVAILABLE                  portAvailable3()
105
#else
106
#ifdef USE_PORT_4
107
#define INIT_PORT(w,x,y,z)               initPort4(w,x,y,z)
108
#define TX_WRITE(x)                     txWrite4(x)
109
#define RX_READ                         rxRead4()
110
#define PORT_AVAILABLE                  portAvailable4()
111
#else
112
#error "Please choose an uart port..."
113
#endif
114
#endif
115
#endif
116
#endif
117

    
118

    
119
int main(void) {
120
    
121
    
122
    uint8_t ctrlReg;
123
    uint8_t masterBuffer[64], bufferA[64], bufferB[64], bufferC[64], bufferD[64];
124
    uint8_t VCOMAIndex = 0, VCOMBIndex = 0, VCOMCIndex = 0, VCOMDIndex = 0, MCOMIndex;
125
    uint16_t MCOM_counter = 0;
126
    uint16_t VCOMA_counter = 0;
127
    uint16_t VCOMB_counter = 0;
128
    uint16_t VCOMC_counter = 0;
129
    uint16_t VCOMD_counter = 0;
130
    uint8_t debug;
131
    
132
    bool writtenStatus = false;
133
    bool readStatus[] = {false, false, false, false, false};
134
 
135
    setWait(5000);
136
    
137
    
138
    for(int i = 0; i < 64; i++)
139
    {
140
        bufferA[i] = 0;
141
    }
142
    for(int i = 0; i < 64; i++)
143
    {
144
        bufferB[i] = 0;
145
    }
146
    for(int i = 0; i < 64; i++)
147
    {
148
        bufferC[i] = 0;
149
    }
150
    for(int i = 0; i < 64; i++)
151
    {
152
        bufferD[i] = 0;
153
    }
154
    
155
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, _FREQSEL_REG_WR); //switch to 24 MHz
156
    
157
    
158
    
159
    //Enable pins (Port direction)
160
    ADDR_ENABLE;        //Address pins
161
    ENABLE_WR_RD_PINS;  //Read and Write pins
162
    ENABLE_CS_PINS;     //Chip select pins
163
    ENABLE_RESET_PIN;   //Reset pin
164
    
165
    //////////////////////////////////////////////////////////////
166
    //Remember to put high level on cs pins to disable devices...
167
    SETCSA;
168
    SETCSB;
169
    SETCSC;
170
    SETCSD;
171
    //Also don't forget IOR and IOW
172
    SETWR;
173
    SETRD;
174
    //////////////////////////////////////////////////////////////
175
    
176
    
177
    ////////////////////////////////////////
178
    //init TL16C IC
179
    SETRST; 
180
    //_delay_ms(10);
181
    setWait(100);
182
    CLRRST;
183
    setWait(5);
184
    ////////////////////////////////////////
185
    
186
    //Init virtual COM ports
187
    //TODO : Set EEPROM CFG here
188
    initPortA(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
189
    initPortB(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
190
    initPortC(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
191
    initPortD(DL_9600_BAUDS, F8BIT_MODE, TL16C_NO_PARITY, ONE_STOPBIT);
192
    
193
    //Master Port
194
    INIT_PORT(UART_BAUD_VALUE, F8BIT_MODE, ONE_STOPBIT, AVR32_NO_PARITY);
195
    
196
    setWait(500);
197
    ctrlReg = 0;
198
    
199
    
200
    timerInit(60000); //10 ms interrupt
201
    sei(); //never forget to enable global interrupt mask !
202
    
203
    PORTA.DIR = 0x3F;
204
    
205
    
206
    
207
    while(1)
208
    {
209
        if(vcom_choose > 3)
210
        {
211
                asm("nop");
212
                asm("nop");
213
                asm("nop");
214
                asm("nop");
215
        }
216
        debug++;
217
        
218
        if(debug == 0x07)
219
            asm("nop");
220
        
221
        ////////////////////////////////////////////////////////
222
        //Read UART A
223
        
224
        
225
        if(portA_available()) //Check if one byte available
226
        {
227
            readStatus[PORT_VCOMA_INDEX] = true;
228
            bufferA[VCOMAIndex] = rxReadA(); 
229
            VCOMAIndex++; 
230
            //if(VCOMAIndex > 64)
231
            //    VCOMAIndex = 0;
232
            VCOMA_counter = 0; //for frame timeout
233
        }
234
        
235
        ////////////////////////////////////////////////////////
236
        //Read UART B
237
        
238
        
239
        if(portB_available()) //Check if one byte available
240
        {
241
            readStatus[PORT_VCOMB_INDEX] = true;
242
            bufferB[VCOMBIndex] = rxReadB();
243
            VCOMBIndex++; 
244
            //if(VCOMBIndex > 64)
245
            //    VCOMBIndex = 0;
246
            VCOMB_counter = 0; //for frame timeout  
247
        }
248
        
249
        
250
        ////////////////////////////////////////////////////////
251
        //Read UART C
252
        
253
        
254
        if(portC_available()) //Check if one byte available
255
        {
256
            readStatus[PORT_VCOMC_INDEX] = true;
257
            bufferC[VCOMCIndex] = rxReadC();
258
            VCOMCIndex++; 
259
            //if(VCOMCIndex > 64)
260
            //    VCOMCIndex = 0;
261
            VCOMC_counter = 0; //for frame timeout 
262
        }
263
        
264
        
265
        
266
        ////////////////////////////////////////////////////////
267
        //Read UART D
268
        
269
        
270
        if(portD_available()) //Check if one byte available
271
        {
272
            readStatus[PORT_VCOMD_INDEX] = true;
273
            bufferD[VCOMDIndex] = rxReadD();
274
            VCOMDIndex++; 
275
            //if(VCOMDIndex > 64)
276
            //    VCOMDIndex = 0;
277
            VCOMD_counter = 0; //for frame timeout
278
        }
279
        
280
        
281
        ////////////////////////////////////////////////////////
282
        //Read UART Master
283
        
284
        
285
        if(PORT_AVAILABLE > 0) //check if we have bytes to read
286
        {
287
            readStatus[PORT_MCOM_INDEX] = true;
288
            masterBuffer[MCOMIndex] = RX_READ; //store byte into buffer
289
            MCOMIndex++; //increment to next byte
290
            //if(MCOMIndex > 64)
291
            //    MCOMIndex = 0;
292
            MCOM_counter = 0; //refresh timeout counter
293
        }
294
        
295
        
296
        
297

    
298
        //Timed process (for leds, etc...)
299
        if(getTimerFlag())
300
        {
301
            /////////////////////////////////////////////////////////
302
            //Timeout process
303

    
304
            //For master port
305
            if(MCOMIndex > 0)
306
                MCOM_counter++;
307

    
308
            //For virtual port 1
309
            if(VCOMAIndex > 0)
310
                VCOMA_counter++;
311

    
312
            //For virtual port 2
313
            if(VCOMBIndex > 0)
314
                VCOMB_counter++;
315

    
316
            //For virtual port 3
317
            if(VCOMCIndex > 0)
318
                VCOMC_counter++;
319

    
320
            //For virtual port 4
321
            if(VCOMDIndex > 0)
322
                VCOMD_counter++;
323
            
324
            
325
            senseDebugLeds(&writtenStatus, readStatus);
326
            clearTimerFlag();
327
        }
328
        
329
        
330
            
331
        
332
        
333
        ///////////////////////////////////////
334
        //When buf is ready from master
335
        if(MCOM_counter > SERIAL_PORT_TIMEOUT_COUNT || MCOMIndex >= 64)
336
        {         
337
            //Send buffer to VCOM
338
            VCOM_sendframe(masterBuffer, MCOMIndex);
339
            MCOMIndex = 0; //reset index buffer
340
            MCOM_counter = 0; //reset counter
341
        }
342
        
343
        
344
        ///////////////////////////////////////
345
        //When buf is ready from VCOMA
346

    
347
            if(VCOMA_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMAIndex >= 64)
348
            {
349
                writtenStatus = true;//Say a wrote has been made
350
                //Send buffer to VCOM
351
                MCOM_sendframe(bufferA, VCOMAIndex, PORT_VCOMA_INDEX);
352
                VCOMAIndex = 0; //reset index buffer
353
                VCOMA_counter = 0; //reset counter
354
            }
355
        
356
        
357
        
358
        ///////////////////////////////////////
359
        //When buf is ready from VCOMB
360

    
361
            if(VCOMB_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMBIndex >= 64)
362
            {
363
                //Send buffer to VCOM
364
                MCOM_sendframe(bufferB, VCOMBIndex, PORT_VCOMB_INDEX);
365
                VCOMBIndex = 0; //reset index buffer
366
                VCOMB_counter = 0; //reset counter
367
            }
368
        
369
        
370
        ///////////////////////////////////////
371
        //When buf is ready from VCOMC
372
        if(VCOMC_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMCIndex >= 64)
373
        {
374
            writtenStatus = true;//Say a wrote has been made
375
            //Send buffer to VCOM
376
            MCOM_sendframe(bufferC, VCOMCIndex, PORT_VCOMC_INDEX);
377
            VCOMCIndex = 0; //reset index buffer
378
            VCOMC_counter = 0; //reset counter
379
        }
380

    
381
        
382
        
383

    
384
        if(VCOMD_counter > SERIAL_PORT_TIMEOUT_COUNT || VCOMDIndex >= 64)
385
        {
386

    
387
            writtenStatus = true; //Say a wrote has been made
388
            //Send buffer to VCOM
389
            MCOM_sendframe(bufferD, VCOMDIndex, PORT_VCOMD_INDEX);
390
            VCOMDIndex = 0; //reset index buffer
391
            VCOMD_counter = 0; //reset counter
392
        }
393

    
394
        
395
        ///////////////////////////////////////////////////////////
396
        //Priority check
397
        
398
        //Check if buffer is empty, then put port at lowest priority !
399
        
400
        if(VCOMAIndex == 0) //no buffer ?
401
        {
402
            vcom_priority[PORT_VCOMA_INDEX] = 0; //no priority
403
        }
404
        
405
        
406
        if(VCOMBIndex == 0) //no buffer ?
407
        {
408
            vcom_priority[PORT_VCOMB_INDEX] = 0; //no priority
409
        }
410
        
411
        
412
        if(VCOMCIndex == 0) //no buffer ?
413
        {
414
            vcom_priority[PORT_VCOMC_INDEX] = 0; //no priority
415
        }
416
        
417
        
418
        if(VCOMDIndex == 0) //no buffer ?
419
        {
420
            vcom_priority[PORT_VCOMD_INDEX] = 0; //no priority
421
        }
422
        
423
        
424
    }
425
    
426
    
427
        
428
    return 0;
429
}
430

    
431

    
432

    
433

    
434
///////////////////////////////////////////////////////////
435
//Functions / macros
436

    
437
//Send a frame from virtual port to master port
438

    
439
void MCOM_sendframe(uint8_t *data, uint8_t n, uint8_t port)
440
{
441
    //////////////////////////
442
    //Send frame
443
    
444
    TX_WRITE(0x02); //STX
445
    TX_WRITE(port + CESAR_SHIFT); //Which virtual port called master port ?
446
    TX_WRITE(FRAME_ADDR_1); //ADDR
447
    TX_WRITE(FRAME_ADDR_2); //ADDR
448
    
449
    for(uint8_t i = 0; i < n; i++) //DATA
450
        TX_WRITE(data[i]);
451
    
452
    TX_WRITE(LF_CHAR); //End of frame
453
    TX_WRITE(CR_CHAR); //End of frame
454
    //////////////////////////
455
}
456

    
457
//////////////////////////////////////////////////////////////////////////////////////////
458
//Send a frame from master port to virtual port (that calculate whose port to send ?)
459

    
460
void VCOM_sendframe(uint8_t *data, uint8_t n)
461
{
462
    uint16_t addrFunctions[] = {&txWriteA, &txWriteB, &txWriteC, &txWriteD }; //list of available functions addresses
463
    void (*localTxWrite)(); //function pointer
464

    
465
    ////////////////////////////////
466
    //To debugger read section
467
    
468
    
469
    
470
    for(int i = 0; i < 256; i++)
471
        global_debugBuffer[i] = data[i];
472
    
473
    if(global_n == 0x02)
474
    {
475
        asm("nop");
476
    }
477
    if(global_debugBuffer[1] == 0x03)
478
    {
479
        asm("nop");
480
    }
481
    ////////////////////////////////
482
    
483
    //At first, check if first byte is the start of text
484
    if(data[0] == STX)
485
    {
486
        if(data[2] == FRAME_ADDR_1 && data[3] == FRAME_ADDR_2) //check if we have the MUX address identifier
487
        {    
488
            if(data[n-1] == CR_CHAR) //check the end of text (second byte)
489
            {
490
                if(data[n-2] == LF_CHAR) //check the end of text (first byte)
491
                {
492
                    data[1]-=CESAR_SHIFT; //convert port index to buffer equivalent
493
                    localTxWrite = addrFunctions[(data[1] < 3) ? data[1] : 3 ]; //data[3]
494
                    for(int i = 4; i < n-2; i++) //send frame without (STX + FRAME_ADDR_B1 + FRAME_ADDR_B2 + LF_CHAR + CR_CHAR)
495
                    {
496
                        localTxWrite(data[i]);
497
                    }
498
                    
499
                }
500
            }
501
        }
502
    }
503
}
504

    
505

    
506

    
507

    
508

    
509

    
510

    
511
void bootSequence(void)
512
{
513
    debugLedsTest();
514
}
515

    
516

    
517

    
518

    
519
/**
520
 <p><b>void debugLedsTest(void)</b></p>
521
 <p><b>Debug leds test sequence</b></p>
522
 */
523
void debugLedsTest(void)
524
{
525

    
526
    PORTA.OUT = 1;
527
    for(int i = 0; i < 6; i++)
528
    {
529
        PORTA.OUT <<= 1;
530
        _delay_ms(125);
531
    }
532
    PORTA.OUT = 0;
533
}
534

    
535
/**
536
 <p><b>void senseDebugLeds(void)</b></p>
537
 <p><b>Call this to update leds status</b></p>
538
 */
539
void senseDebugLeds(bool *hasWritten, bool *hasRead)
540
{
541
    
542

    
543
    
544
    ///////////////////////////
545
    //Check Master Port
546
    if(*hasWritten)
547
    {
548
        PORTA.OUT |= 0x20;
549
        *hasWritten = false;
550
    }
551
    else
552
        PORTA.OUT &= ~(0x20);
553
    
554
    if(hasRead[PORT_MCOM_INDEX])
555
    {
556
        PORTA.OUT |= 0x10;
557
        hasRead[PORT_MCOM_INDEX] = false;
558
    }
559
    else
560
        PORTA.OUT &= ~(0x10);
561
    
562
    ///////////////////////////
563
    //Check VCOMA
564
    if(hasRead[PORT_VCOMA_INDEX])
565
    {
566
        PORTA.OUT |= 0x01;
567
        hasRead[PORT_VCOMA_INDEX] = false;
568
    }
569
    else
570
        PORTA.OUT &= ~(0x01);
571
    
572
    ///////////////////////////
573
    //Check VCOMB
574
    if(hasRead[PORT_VCOMB_INDEX])
575
    {
576
        PORTA.OUT |= 0x02;
577
        hasRead[PORT_VCOMB_INDEX] = false;
578
    }
579
    else
580
        PORTA.OUT &= ~(0x02);
581
    
582
    ///////////////////////////
583
    //Check VCOMC
584
    if(hasRead[PORT_VCOMC_INDEX])
585
    {
586
        PORTA.OUT |= 0x04;
587
        hasRead[PORT_VCOMC_INDEX] = false;
588
    }
589
    else
590
        PORTA.OUT &= ~(0x04);
591
    
592
    
593
    ///////////////////////////
594
    //Check VCOMD
595
    if(hasRead[PORT_VCOMD_INDEX])
596
    {
597
        PORTA.OUT |= 0x08;
598
        hasRead[PORT_VCOMD_INDEX] = false;
599
    }
600
    else
601
        PORTA.OUT &= ~(0x08);
602
}
603

    
604

    
605

    
606

    
607

    
608

    
609

    
610