root / Version 0.9 / RS232_MUX.X / main.c @ 10dcb6e9
Historique | Voir | Annoter | Télécharger (8,117 ko)
1 |
/*
|
---|---|
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 |
|
299 |
|