Statistiques
| Branche: | Révision:

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

Historique | Voir | Annoter | Télécharger (8,117 ko)

1 10dcb6e9 Enzo Niro
/*
2
 * File:   main.c
3
 * Author: eniro
4
 *
5
 * Created on March 25, 2024, 3:51 PM
6
 */
7
8
#define F_CPU 24000000UL
9
10
#include <xc.h>
11
#include <math.h>
12
#include <stdlib.h>
13
#include <util/delay.h>
14
#include <avr/interrupt.h>
15
#include <avr/eeprom.h>
16
17
#include "hardware_uart.h"
18
#include "hardware_timer.h"
19
#include "frame_definitions.h"
20
21
//USART setup
22
23
//To calculate BAUD value register -> BAUD = 64*FCLK/(16*FBAUDS)
24
#define UART_BAUD_VALUE     833 // 10000 is equivalent as 9600 bauds according to datasheet
25
#define USART0_REG          0x3 
26
#define BOOT_MSG            "RS232-MUX\r\n"
27
28
29
30
//OSC. setup
31
#define FREQSEL     0x9
32
#define _FREQSEL_REG_WR     ((FREQSEL) << 2)
33
#define _USART0_REG_WR      (USART0_REG & 0x7)
34
35
36
37
38
//////////////////////////////////////////////////////////////
39
//Prototypes
40
41
void bootSequence(void);
42
43
//reset watchdog counter
44
#define WATCHDOG_RESET      asm("WDR")
45
46
uint8_t global_debugBuffer[256];
47
uint8_t global_n = 0;
48
49
50
int main(void) {
51
    
52
    
53
54
    ////////////////////////////////////////////////////////////
55
    //Local variables
56
    
57
    const char *boot_msg = BOOT_MSG;
58
    
59
    cfgPort cfgVCOM1, cfgVCOM2, cfgVCOM3, cfgVCOM4;
60
    uint8_t ledsCfg;
61
    
62
    
63
    
64
    //Output buffer
65
    uint8_t MCOMBuf[256], VCOM1Buf[256], VCOM2Buf[256], VCOM3Buf[256], VCOM4Buf[256];
66
    //Output buffer index 
67
    uint8_t MCOMIndex = 0, VCOM1Index = 0, VCOM2Index = 0, VCOM3Index = 0, VCOM4Index = 0;
68
    //local timer counter for local process (blink led, ect...)
69
    uint32_t timerCnt = 0;
70
    //local timer for counting how many cycles passed since we've got activity on serial port ?
71
    uint32_t serialTimer = 0;
72
    
73
    //Counter to make a timeout if all data has passed
74
    uint8_t MCOM_counter = 0;
75
    uint8_t VCOM1_counter = 0;
76
    uint8_t VCOM2_counter = 0;
77
    uint8_t VCOM3_counter = 0;
78
    uint8_t VCOM4_counter = 0;
79
    
80
    
81
    for(int i = 0; i < 256; i++)
82
    {
83
        MCOMBuf[i] = 0;
84
        VCOM1Buf[i] = 0;
85
        VCOM2Buf[i] = 0;
86
        VCOM3Buf[i] = 0;
87
        VCOM4Buf[i] = 0;
88
    }
89
    
90
   
91
    PORTD.DIR = 0x01; // DEBUG LED
92
    //PORTMUX.USARTROUTEA = _USART0_REG_WR; //set TX and RX on PD4 and PD5 pins
93
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, _FREQSEL_REG_WR); //switch to 24 MHz
94
    
95
    ///////////////////////////////////////////
96
    //Prepare VCOM configuration
97
    
98
    //At first read EEPROM !
99
    getEEPROMCfg(); //Get serial port configuration
100
    ledsCfg = getDebugLedsConfiguration(); //get debug leds configuration
101
    
102
    //And then, read configuration for each port...
103
    
104
    readConfiguration(&cfgVCOM1, 0);
105
    readConfiguration(&cfgVCOM2, 1);
106
    readConfiguration(&cfgVCOM3, 2);
107
    readConfiguration(&cfgVCOM4, 3);
108
    
109
    ///////////////////////////////////////////
110
    //Interrupt & serial port setup
111
    
112
    //Set port with debug leds
113
    initPort0(UART_BAUD_VALUE, (ledsCfg & 0x1), F8BIT_MODE, ONE_STOPBIT, NO_PARITY); //init master port with debug leds
114
    initPort1(cfgVCOM1.baud, (ledsCfg & 0x2) >> 1, cfgVCOM1.dataByte, cfgVCOM1.stopBit, cfgVCOM1.parity); //init vcom1 port with debug leds
115
    initPort2(cfgVCOM2.baud, (ledsCfg & 0x4) >> 2, cfgVCOM2.dataByte, cfgVCOM2.stopBit, cfgVCOM2.parity); //init vcom2 port with debug leds
116
    initPort3(cfgVCOM3.baud, (ledsCfg & 0x8) >> 3, cfgVCOM3.dataByte, cfgVCOM3.stopBit, cfgVCOM3.parity); //init vcom3 port with debug leds
117
    initPort4(cfgVCOM4.baud, (ledsCfg & 0x16) >> 4, cfgVCOM4.dataByte, cfgVCOM4.stopBit, cfgVCOM4.parity); //init vcom4 port  with debug leds     
118
    //Timer init
119
    //Setup for interrupt every 25ms
120
    timerInterruptInit(0x2EE0);
121
    
122
    sei(); //never forget to enable global interrupt mask !
123
    
124
    ///////////////////////////////////////////
125
    
126
    //Debug led on boot sequence
127
    WATCHDOG_RESET; //reset WD counter
128
    bootSequence(); //Launch leds sequence
129
    
130
    
131
    for(uint8_t i = 0; i < 11; i++)
132
    {
133
        txWrite0(boot_msg[i]);
134
    }
135
    
136
    while(1)
137
    {
138
        WATCHDOG_RESET; //Always call this to prevent undesired boot...
139
        
140
        //if(portAvailable0() > 0) //check if we have bytes to read
141
        if(portAvailable0() > 0)
142
        {
143
            MCOMBuf[MCOMIndex] = rxRead0(); //store byte into buffer
144
            MCOMIndex++; //increment to next byte
145
            MCOM_counter = 0; //refresh timeout counter
146
        }
147
        
148
        if(portAvailable1() > 0) //check if we have bytes to read
149
        {
150
            VCOM1Buf[VCOM1Index] = rxRead1(); //store byte into buffer
151
            VCOM1Index++; //increment to next byte
152
            VCOM1_counter = 0; //refresh timeout counter
153
        }
154
        
155
        if(portAvailable2() > 0) //check if we have bytes to read
156
        {
157
            VCOM2Buf[VCOM2Index] = rxRead2(); //store byte into buffer
158
            VCOM2Index++; //increment to next byte
159
            VCOM2_counter = 0; //refresh timeout counter
160
        }
161
        
162
        if(portAvailable3() > 0) //check if we have bytes to read
163
        {
164
            VCOM3Buf[VCOM3Index] = rxRead3(); //store byte into buffer
165
            VCOM3Index++; //increment to next byte
166
            VCOM3_counter = 0; //refresh timeout counter
167
        }
168
        
169
        if(portAvailable4() > 0) //check if we have bytes to read
170
        {
171
            VCOM4Buf[VCOM4Index] = rxRead4(); //store byte into buffer
172
            VCOM4Index++; //increment to next byte
173
            VCOM4_counter = 0; //refresh timeout counter
174
        }
175
        
176
        
177
        //if timeout
178
        if(MCOM_counter > 10)
179
        {
180
            MCOM_sendframe(MCOMBuf, MCOMIndex);
181
            //Clear the buffer
182
            for(uint8_t i = 0; i < MCOMIndex; i++)
183
            {
184
                MCOMBuf[i] = 0;
185
            }
186
            MCOMIndex = 0;
187
            MCOM_counter = 0;
188
        }
189
        
190
        
191
        //NOTE : Not sure that stuff will be useful...
192
        //Just in case if bytes does not match, clear counter
193
        if(MCOMIndex >= 255)
194
            MCOMIndex = 0;
195
        
196
        if(VCOM1Index >= 255)
197
            VCOM1Index = 0;
198
        
199
        if(VCOM2Index >= 255)
200
            VCOM2Index = 0;
201
        
202
        if(VCOM3Index >= 255)
203
            VCOM3Index = 0;
204
        
205
        if(VCOM4Index >= 255)
206
            VCOM4Index = 0;
207
        
208
        
209
        //Refresh led status
210
        if(abs(getTimerCounts() - timerCnt) >= 25)
211
        {
212
            senseDebugLeds();
213
            timerCnt = getTimerCounts();
214
        }
215
        
216
        //count
217
        if(abs(getTimerCounts() - serialTimer) >= 1)
218
        {
219
            //prevent incrementing counter if no bytes available...
220
            if(MCOMIndex > 0)
221
                MCOM_counter++;
222
            
223
            VCOM1_counter++;
224
            VCOM2_counter++;
225
            VCOM3_counter++;
226
            VCOM4_counter++;
227
            serialTimer = getTimerCounts();
228
        }
229
        
230
    }
231
    
232
    
233
    
234
        
235
    return 0;
236
}
237
238
239
240
241
///////////////////////////////////////////////////////////
242
//Functions / macros
243
244
//Send a frame from master port that calculate whose port to send ?
245
void MCOM_sendframe(uint8_t *data, uint8_t n)
246
{
247
    uint16_t addrFunctions[] = {&txWrite1, &txWrite2, &txWrite3, &txWrite4 }; //list of available functions addresses
248
    void (*localTxWrite)(); //function pointer
249
    
250
    global_n = n;
251
    
252
    //To read buffer with debugger
253
    for(int i = 0; i < 256; i++)
254
        global_debugBuffer[i] = data[i];
255
    
256
    if(global_n == 0x02)
257
    {
258
        asm("nop");
259
    }
260
    if(global_debugBuffer[1] == 0x03)
261
    {
262
        asm("nop");
263
    }
264
    //At first, check if first byte is the start of text
265
    if(data[0] == STX)
266
    {
267
        if(data[2] == FRAME_ADDR_1 && data[3] == FRAME_ADDR_2) //check if we have the MUX address identifier
268
        {    
269
            if(data[n-1] == CR_CHAR) //check the end of text (second byte)
270
            {
271
                if(data[n-2] == LF_CHAR) //check the end of text (first byte)
272
                {
273
                    localTxWrite = addrFunctions[(data[1] < 3) ? data[1] : 3 ]; //data[3]
274
                    for(int i = 4; i < n-2; i++) //send frame without (STX + FRAME_ADDR_B1 + FRAME_ADDR_B2 + LF_CHAR + CR_CHAR)
275
                    {
276
                        localTxWrite(data[i]);
277
                    }
278
                    
279
                }
280
            }
281
        }
282
    }
283
}
284
285
286
287
void bootSequence(void)
288
{
289
    debugLedsTest();
290
}
291
292
293
294
295
296
297
298