1
- /* *******************************************************************
2
- Ethernet and serial interface functions
3
-
4
- startSerial()
5
- - starts HW serial interface which we use for RS485 line
6
-
7
- charTime(), charTimeOut(), frameDelay()
8
- - calculate Modbus RTU character timeout and inter-frame delay
9
-
10
- startEthernet()
11
- - initiates ethernet interface
12
- - if enabled, gets IP from DHCP
13
- - starts all servers (Modbus TCP, UDP, web server)
14
-
15
- resetFunc()
16
- - well... resets Arduino
17
-
18
- maintainDhcp()
19
- - maintain DHCP lease
20
-
21
- maintainUptime()
22
- - maintains up time in case of millis() overflow
23
-
24
- maintainCounters(), rollover()
25
- - synchronizes roll-over of data counters to zero
26
-
27
- resetStats()
28
- - resets Modbus stats
29
-
30
- generateMac()
31
- - generate random MAC using pseudo random generator (faster and than build-in random())
32
-
33
- manageSockets()
34
- - closes sockets which are waiting to be closed or which refuse to close
35
- - forwards sockets with data available (webserver or Modbus TCP) for further processing
36
- - disconnects (closes) sockets which are too old / idle for too long
37
- - opens new sockets if needed (and if available)
38
-
39
- CreateTrulyRandomSeed()
40
- - seed pseudorandom generator using watch dog timer interrupt (works only on AVR)
41
- - see https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed
42
-
43
-
44
- + preprocessor code for identifying microcontroller board
45
-
46
- ***************************************************************** */
47
-
48
-
1
+ /* *************************************************************************/
2
+ /* !
3
+ @brief Initiates HW serial interface which we use for the RS485 line.
4
+ */
5
+ /* *************************************************************************/
49
6
void startSerial () {
50
7
mySerial.begin ((data.config .baud * 100UL ), data.config .serialConfig );
51
8
#ifdef RS485_CONTROL_PIN
@@ -54,7 +11,7 @@ void startSerial() {
54
11
#endif /* RS485_CONTROL_PIN */
55
12
}
56
13
57
- // number of bits per character (11 in default Modbus RTU settings)
14
+ // Number of bits per character (11 in default Modbus RTU settings)
58
15
byte bitsPerChar () {
59
16
byte bits =
60
17
1 + // start bit
@@ -64,7 +21,7 @@ byte bitsPerChar() {
64
21
return bits;
65
22
}
66
23
67
- // character timeout in micros
24
+ // Character timeout in micros
68
25
uint32_t charTimeOut () {
69
26
if (data.config .baud <= 192 ) {
70
27
return (15000UL * bitsPerChar ()) / data.config .baud ; // inter-character time-out should be 1,5T
@@ -73,7 +30,7 @@ uint32_t charTimeOut() {
73
30
}
74
31
}
75
32
76
- // minimum frame delay in micros
33
+ // Minimum frame delay in micros
77
34
uint32_t frameDelay () {
78
35
if (data.config .baud <= 192 ) {
79
36
return (35000UL * bitsPerChar ()) / data.config .baud ; // inter-frame delay should be 3,5T
@@ -82,6 +39,12 @@ uint32_t frameDelay() {
82
39
}
83
40
}
84
41
42
+ /* *************************************************************************/
43
+ /* !
44
+ @brief Initiates ethernet interface, if DHCP enabled, gets IP from DHCP,
45
+ starts all servers (UDP, web server).
46
+ */
47
+ /* *************************************************************************/
85
48
void startEthernet () {
86
49
if (ETH_RESET_PIN != 0 ) {
87
50
pinMode (ETH_RESET_PIN, OUTPUT);
@@ -112,8 +75,18 @@ void startEthernet() {
112
75
#endif
113
76
}
114
77
78
+ /* *************************************************************************/
79
+ /* !
80
+ @brief Resets Arduino (works only on AVR chips).
81
+ */
82
+ /* *************************************************************************/
115
83
void (*resetFunc)(void ) = 0 ; // declare reset function at address 0
116
84
85
+ /* *************************************************************************/
86
+ /* !
87
+ @brief Checks SPI connection to the W5X00 chip.
88
+ */
89
+ /* *************************************************************************/
117
90
void checkEthernet () {
118
91
static byte attempts = 0 ;
119
92
IPAddress tempIP = Ethernet.localIP ();
@@ -128,6 +101,11 @@ void checkEthernet() {
128
101
checkEthTimer.sleep (CHECK_ETH_INTERVAL);
129
102
}
130
103
104
+ /* *************************************************************************/
105
+ /* !
106
+ @brief Maintains DHCP lease.
107
+ */
108
+ /* *************************************************************************/
131
109
#ifdef ENABLE_DHCP
132
110
void maintainDhcp () {
133
111
if (data.config .enableDhcp && dhcpSuccess == true ) { // only call maintain if initial DHCP request by startEthernet was successfull
@@ -136,6 +114,11 @@ void maintainDhcp() {
136
114
}
137
115
#endif /* ENABLE_DHCP */
138
116
117
+ /* *************************************************************************/
118
+ /* !
119
+ @brief Maintains uptime in case of millis() overflow.
120
+ */
121
+ /* *************************************************************************/
139
122
#ifdef ENABLE_EXTENDED_WEBUI
140
123
void maintainUptime () {
141
124
uint32_t milliseconds = millis ();
@@ -152,8 +135,12 @@ void maintainUptime() {
152
135
}
153
136
#endif /* ENABLE_EXTENDED_WEBUI */
154
137
138
+ /* *************************************************************************/
139
+ /* !
140
+ @brief Synchronizes roll-over of data counters to zero.
141
+ */
142
+ /* *************************************************************************/
155
143
bool rollover () {
156
- // synchronize roll-over of run time, data counters and modbus stats to zero, at 0xFFFFFF00
157
144
const uint32_t ROLLOVER = 0xFFFFFF00 ;
158
145
for (byte i = 0 ; i < ERROR_LAST; i++) {
159
146
if (data.errorCnt [i] > ROLLOVER) {
@@ -173,7 +160,11 @@ bool rollover() {
173
160
return false ;
174
161
}
175
162
176
- // resets counters to 0: data.errorCnt, data.rtuCnt, data.ethCnt
163
+ /* *************************************************************************/
164
+ /* !
165
+ @brief Resets error stats, RTU counter and ethernet data counter.
166
+ */
167
+ /* *************************************************************************/
177
168
void resetStats () {
178
169
memset (data.errorCnt , 0 , sizeof (data.errorCnt ));
179
170
#ifdef ENABLE_EXTENDED_WEBUI
@@ -183,7 +174,12 @@ void resetStats() {
183
174
#endif /* ENABLE_EXTENDED_WEBUI */
184
175
}
185
176
186
- // generate new MAC (bytes 0, 1 and 2 are static, bytes 3, 4 and 5 are generated randomly)
177
+ /* *************************************************************************/
178
+ /* !
179
+ @brief Generate random MAC using pseudo random generator,
180
+ bytes 0, 1 and 2 are static (MAC_START), bytes 3, 4 and 5 are generated randomly
181
+ */
182
+ /* *************************************************************************/
187
183
void generateMac () {
188
184
// Marsaglia algorithm from https://github.com/RobTillaart/randomHelpers
189
185
seed1 = 36969L * (seed1 & 65535L ) + (seed1 >> 16 );
@@ -196,21 +192,29 @@ void generateMac() {
196
192
}
197
193
}
198
194
195
+ /* *************************************************************************/
196
+ /* !
197
+ @brief Write (update) data to Arduino EEPROM.
198
+ */
199
+ /* *************************************************************************/
199
200
void updateEeprom () {
200
201
eepromTimer.sleep (EEPROM_INTERVAL * 60UL * 60UL * 1000UL ); // EEPROM_INTERVAL is in hours, sleep is in milliseconds!
201
202
data.eepromWrites ++; // we assume that at least some bytes are written to EEPROM during EEPROM.update or EEPROM.put
202
203
EEPROM.put (DATA_START, data);
203
204
}
204
205
205
- #if MAX_SOCK_NUM == 8
206
- uint32_t lastSocketUse[MAX_SOCK_NUM] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
207
- byte socketInQueue[MAX_SOCK_NUM] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
208
- #elif MAX_SOCK_NUM == 4
209
- uint32_t lastSocketUse[MAX_SOCK_NUM] = { 0 , 0 , 0 , 0 };
210
- byte socketInQueue[MAX_SOCK_NUM] = { 0 , 0 , 0 , 0 };
211
- #endif
212
206
213
- // from https://github.com/SapientHetero/Ethernet/blob/master/src/socket.cpp
207
+ uint32_t lastSocketUse[MAX_SOCK_NUM];
208
+ byte socketInQueue[MAX_SOCK_NUM];
209
+ /* *************************************************************************/
210
+ /* !
211
+ @brief Closes sockets which are waiting to be closed or which refuse to close,
212
+ forwards sockets with data available for further processing by the webserver,
213
+ disconnects (closes) sockets which are too old (idle for too long), opens
214
+ new sockets if needed (and if available).
215
+ From https://github.com/SapientHetero/Ethernet/blob/master/src/socket.cpp
216
+ */
217
+ /* *************************************************************************/
214
218
void manageSockets () {
215
219
uint32_t maxAge = 0 ; // the 'age' of the socket in a 'disconnectable' state that was last used the longest time ago
216
220
byte oldest = MAX_SOCK_NUM; // the socket number of the 'oldest' disconnectable socket
@@ -308,6 +312,12 @@ void manageSockets() {
308
312
// we do not need SPI.beginTransaction(SPI_ETHERNET_SETTINGS) or SPI.endTransaction() ??
309
313
}
310
314
315
+ /* *************************************************************************/
316
+ /* !
317
+ @brief Disconnect or close a socket.
318
+ @param s Socket number.
319
+ */
320
+ /* *************************************************************************/
311
321
void disconSocket (byte s) {
312
322
if (W5100.readSnSR (s) == SnSR::ESTABLISHED) {
313
323
W5100.execCmdSn (s, Sock_DISCON); // Sock_DISCON does not close LISTEN sockets
@@ -317,7 +327,13 @@ void disconSocket(byte s) {
317
327
}
318
328
}
319
329
320
- // https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed
330
+
331
+ /* *************************************************************************/
332
+ /* !
333
+ @brief Seed pseudorandom generator using watch dog timer interrupt (works only on AVR).
334
+ See https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed
335
+ */
336
+ /* *************************************************************************/
321
337
void CreateTrulyRandomSeed () {
322
338
seed1 = 0 ;
323
339
nrot = 32 ; // Must be at least 4, but more increased the uniformity of the produced seeds entropy.
@@ -344,11 +360,9 @@ ISR(WDT_vect) {
344
360
seed1 = seed1 ^ TCNT1L;
345
361
}
346
362
347
- // Board definitions
363
+ // Preprocessor code for identifying microcontroller board
348
364
#if defined(TEENSYDUINO)
349
-
350
365
// --------------- Teensy -----------------
351
-
352
366
#if defined(__AVR_ATmega32U4__)
353
367
#define BOARD F (" Teensy 2.0" )
354
368
#elif defined(__AVR_AT90USB1286__)
@@ -366,9 +380,7 @@ ISR(WDT_vect) {
366
380
#else
367
381
#define BOARD F (" Unknown Board" )
368
382
#endif
369
-
370
383
#else // --------------- Arduino ------------------
371
-
372
384
#if defined(ARDUINO_AVR_ADK)
373
385
#define BOARD F (" Arduino Mega Adk" )
374
386
#elif defined(ARDUINO_AVR_BT) // Bluetooth
@@ -422,5 +434,4 @@ ISR(WDT_vect) {
422
434
#else
423
435
#define BOARD F (" Unknown Board" )
424
436
#endif
425
-
426
437
#endif
0 commit comments