1- /* *******************************************************************
2- Ethernet interface functions
3-
4- startEthernet()
5- - initiates ethernet interface
6- - if enabled, gets IP from DHCP
7- - starts all servers (Modbus TCP, UDP, web server)
8-
9- resetFunc()
10- - well... resets Arduino
11-
12- maintainDhcp()
13- - maintain DHCP lease
14-
15- maintainUptime()
16- - maintains up time in case of millis() overflow
17-
18- maintainCounters(), rollover()
19- - synchronizes roll-over of data counters to zero
20-
21- resetStats(), resetEepromStats()
22- - resets P1P2 stats and Daikin EEPROM stats
23-
24- generateMac()
25- - generate random MAC using pseudo random generator (faster and than build-in random())
26-
27- manageSockets()
28- - closes sockets which are waiting to be closed or which refuse to close
29- - forwards sockets with data available for further processing by the webserver
30- - disconnects (closes) sockets which are too old / idle for too long
31- - opens new sockets if needed (and if available)
32-
33- CreateTrulyRandomSeed()
34- - seed pseudorandom generator using watch dog timer interrupt (works only on AVR)
35- - see https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed
36-
37-
38- + preprocessor code for identifying microcontroller board
39-
40- ***************************************************************** */
41-
42-
1+ /* *************************************************************************/
2+ /* !
3+ @brief Initiates ethernet interface, if DHCP enabled, gets IP from DHCP,
4+ starts all servers (UDP, web server).
5+ */
6+ /* *************************************************************************/
437void startEthernet () {
448 if (ETH_RESET_PIN != 0 ) {
459 pinMode (ETH_RESET_PIN, OUTPUT);
@@ -68,8 +32,18 @@ void startEthernet() {
6832#endif
6933}
7034
35+ /* *************************************************************************/
36+ /* !
37+ @brief Resets Arduino (works only on AVR chips).
38+ */
39+ /* *************************************************************************/
7140void (*resetFunc)(void ) = 0 ; // declare reset function at address 0
7241
42+ /* *************************************************************************/
43+ /* !
44+ @brief Maintains DHCP lease.
45+ */
46+ /* *************************************************************************/
7347#ifdef ENABLE_DHCP
7448void maintainDhcp () {
7549 if (data.config .enableDhcp && dhcpSuccess == true ) { // only call maintain if initial DHCP request by startEthernet was successfull
@@ -78,6 +52,11 @@ void maintainDhcp() {
7852}
7953#endif /* ENABLE_DHCP */
8054
55+ /* *************************************************************************/
56+ /* !
57+ @brief Maintains uptime in case of millis() overflow.
58+ */
59+ /* *************************************************************************/
8160#ifdef ENABLE_EXTENDED_WEBUI
8261void maintainUptime () {
8362 uint32_t milliseconds = millis ();
@@ -94,9 +73,13 @@ void maintainUptime() {
9473}
9574#endif /* ENABLE_EXTENDED_WEBUI */
9675
97- const uint32_t ROLLOVER = 0xFFFFFF00 ;
76+ /* *************************************************************************/
77+ /* !
78+ @brief Synchronizes roll-over of data counters to zero.
79+ */
80+ /* *************************************************************************/
9881bool rollover () {
99- // synchronize roll-over of run time, data counters and modbus stats to zero, at 0xFFFFFF00
82+ const uint32_t ROLLOVER = 0xFFFFFF00 ;
10083 for (byte i = 0 ; i < P1P2_LAST; i++) {
10184 if (data.p1p2Cnt [i] > ROLLOVER) {
10285 return true ;
@@ -115,7 +98,11 @@ bool rollover() {
11598 return false ;
11699}
117100
118- // resets counters to 0: data.p1p2Cnt, data.udpCnt
101+ /* *************************************************************************/
102+ /* !
103+ @brief Resets P1P2 stats, date and UDP stats.
104+ */
105+ /* *************************************************************************/
119106void resetStats () {
120107 memset (data.statsDate , 0 , sizeof (data.statsDate ));
121108 memset (data.p1p2Cnt , 0 , sizeof (data.p1p2Cnt ));
@@ -125,11 +112,21 @@ void resetStats() {
125112#endif /* ENABLE_EXTENDED_WEBUI */
126113}
127114
115+ /* *************************************************************************/
116+ /* !
117+ @brief Resets Daikin EEPROM stats.
118+ */
119+ /* *************************************************************************/
128120void resetEepromStats () {
129121 memset (&data.eepromDaikin , 0 , sizeof (eeprom_t ));
130122}
131123
132- // generate new MAC (bytes 0, 1 and 2 are static, bytes 3, 4 and 5 are generated randomly)
124+ /* *************************************************************************/
125+ /* !
126+ @brief Generate random MAC using pseudo random generator,
127+ bytes 0, 1 and 2 are static (MAC_START), bytes 3, 4 and 5 are generated randomly
128+ */
129+ /* *************************************************************************/
133130void generateMac () {
134131 // Marsaglia algorithm from https://github.com/RobTillaart/randomHelpers
135132 seed1 = 36969L * (seed1 & 65535L ) + (seed1 >> 16 );
@@ -142,19 +139,28 @@ void generateMac() {
142139 }
143140}
144141
142+ /* *************************************************************************/
143+ /* !
144+ @brief Write (update) data to Arduino EEPROM.
145+ */
146+ /* *************************************************************************/
145147void updateEeprom () {
146148 eepromTimer.sleep (EEPROM_INTERVAL * 60UL * 60UL * 1000UL ); // EEPROM_INTERVAL is in hours, sleep is in milliseconds!
147149 data.eepromWrites ++; // we assume that at least some bytes are written to EEPROM during EEPROM.update or EEPROM.put
148150 EEPROM.put (DATA_START, data);
149151}
150152
151- #if MAX_SOCK_NUM == 8
152- uint32_t lastSocketUse[MAX_SOCK_NUM] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
153- #elif MAX_SOCK_NUM == 4
154- uint32_t lastSocketUse[MAX_SOCK_NUM] = { 0 , 0 , 0 , 0 };
155- #endif
156153
157- // from https://github.com/SapientHetero/Ethernet/blob/master/src/socket.cpp
154+ uint32_t lastSocketUse[MAX_SOCK_NUM];
155+ /* *************************************************************************/
156+ /* !
157+ @brief Closes sockets which are waiting to be closed or which refuse to close,
158+ forwards sockets with data available for further processing by the webserver,
159+ disconnects (closes) sockets which are too old (idle for too long), opens
160+ new sockets if needed (and if available).
161+ From https://github.com/SapientHetero/Ethernet/blob/master/src/socket.cpp
162+ */
163+ /* *************************************************************************/
158164void manageSockets () {
159165 uint32_t maxAge = 0 ; // the 'age' of the socket in a 'disconnectable' state that was last used the longest time ago
160166 byte oldest = MAX_SOCK_NUM; // the socket number of the 'oldest' disconnectable socket
@@ -231,9 +237,14 @@ void manageSockets() {
231237 }
232238
233239 SPI.endTransaction (); // Serves to o release the bus for other devices to access it. Since the ethernet chip is the only device
234- // we do not need SPI.beginTransaction(SPI_ETHERNET_SETTINGS) or SPI.endTransaction()
235240}
236241
242+ /* *************************************************************************/
243+ /* !
244+ @brief Disconnect or close a socket.
245+ @param s Socket number.
246+ */
247+ /* *************************************************************************/
237248void disconSocket (byte s) {
238249 if (W5100.readSnSR (s) == SnSR::ESTABLISHED) {
239250 W5100.execCmdSn (s, Sock_DISCON); // Sock_DISCON does not close LISTEN sockets
@@ -243,65 +254,67 @@ void disconSocket(byte s) {
243254 }
244255}
245256
257+ /* *************************************************************************/
258+ /* !
259+ @brief Maintains connection to the P1P2 bus.
260+ */
261+ /* *************************************************************************/
246262void manageController () {
247- if ((controllerState == NOT_SUPPORTED) != data.config .notSupported ) {
248- data.config .notSupported = (controllerState == NOT_SUPPORTED);
249- updateEeprom ();
263+ if (p1p2Timer.isOver ()) {
264+ memset (FxRequests, 0 , sizeof (FxRequests));
250265 }
251- switch (controllerState) {
252- case DISABLED:
253- case DISCONNECTED:
254- case NOT_SUPPORTED:
255- connectionTimer.sleep (data.config .connectTimeout * 1000UL );
256- controllerId = 0x00 ;
257- FxAbsentCnt[0 ] = -1 ;
258- FxAbsentCnt[1 ] = -1 ;
259- cmdQueue.clear ();
260- indoorInQueue = false ;
261- outdoorInQueue = false ;
262- if (data.config .controllerMode == CONTROL_AUTO && controllerState == DISCONNECTED) {
263- controllerState = CONNECTING;
264- }
265- break ;
266- case CONNECTING:
267- case CONNECTED:
268- if (connectionTimer.isOver ()) {
269- if (FxAbsentCnt[0 ] == 0 || FxAbsentCnt[1 ] == 0 ) {
270- controllerState = NOT_SUPPORTED;
271- } else {
272- controllerState = DISCONNECTED;
273- }
274- }
275- if (counterRequestTimer.isOver ()) {
276- counterRequestTimer.sleep (data.config .counterPeriod * 60UL * 1000UL );
277- cmdQueue.push (2 );
278- cmdQueue.push (PACKET_TYPE_COUNTER);
279- cmdQueue.push (0 );
280- if (data.config .sendDataPackets == DATA_CHANGE_AND_REQUEST) {
281- memset (savedPackets, 0xFF , sizeof (savedPackets)); // reset saved packets
282- }
283- }
284- if (daikinIndoor[0 ] == ' \0 ' && indoorInQueue == false ) {
285- cmdQueue.push (2 );
286- cmdQueue.push (PACKET_TYPE_INDOOR_NAME);
287- cmdQueue.push (0 );
288- indoorInQueue = true ;
266+ if (controllerAddr == DISCONNECTED || controllerAddr == CONNECTING) {
267+ cmdQueue.clear ();
268+ indoorInQueue = false ;
269+ outdoorInQueue = false ;
270+ }
271+ if (controllerAddr == DISCONNECTED || (controllerAddr == CONNECTING && data.config .controllerMode == CONTROL_AUTO)) {
272+ connectionTimer.sleep (data.config .connectTimeout * 1000UL );
273+ if (data.config .controllerMode == CONTROL_AUTO) {
274+ controllerAddr = CONNECTING;
275+ }
276+ }
277+ if (connectionTimer.isOver ()) {
278+ if (data.config .controllerMode == CONTROL_AUTO) {
279+ controllerAddr = CONNECTING;
280+ } else {
281+ controllerAddr = DISCONNECTED;
282+ }
283+ }
284+ if (controllerAddr > CONNECTING // Send counter requests only if controller in Write mode (after 00Fx30 request + 40Fx30 reply)
285+ || data.config .controllerMode == CONTROL_AUTO) { // Or if Write to P1P2 is set to Automatically
286+ if (counterRequestTimer.isOver ()) {
287+ counterRequestTimer.sleep (data.config .counterPeriod * 60UL * 1000UL );
288+ cmdQueue.push (2 );
289+ cmdQueue.push (PACKET_TYPE_COUNTER);
290+ cmdQueue.push (0 );
291+ if (data.config .sendDataPackets == DATA_CHANGE_AND_REQUEST) {
292+ memset (savedPackets, 0xFF , sizeof (savedPackets)); // reset saved packets
289293 }
294+ }
295+ if (daikinIndoor[0 ] == ' \0 ' && indoorInQueue == false ) {
296+ cmdQueue.push (2 );
297+ cmdQueue.push (PACKET_TYPE_INDOOR_NAME);
298+ cmdQueue.push (0 );
299+ indoorInQueue = true ;
300+ }
290301#ifdef ENABLE_EXTENDED_WEBUI
291- if (daikinOutdoor[0 ] == ' \0 ' && outdoorInQueue == false ) {
292- cmdQueue.push (2 );
293- cmdQueue.push (PACKET_TYPE_OUTDOOR_NAME);
294- cmdQueue.push (0 );
295- outdoorInQueue = true ;
296- }
302+ if (daikinOutdoor[0 ] == ' \0 ' && outdoorInQueue == false ) {
303+ cmdQueue.push (2 );
304+ cmdQueue.push (PACKET_TYPE_OUTDOOR_NAME);
305+ cmdQueue.push (0 );
306+ outdoorInQueue = true ;
307+ }
297308#endif /* ENABLE_EXTENDED_WEBUI */
298- break ;
299- default :
300- break ;
301309 }
302310}
303311
304- // https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed
312+ /* *************************************************************************/
313+ /* !
314+ @brief Seed pseudorandom generator using watch dog timer interrupt (works only on AVR).
315+ See https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed
316+ */
317+ /* *************************************************************************/
305318void CreateTrulyRandomSeed () {
306319 seed1 = 0 ;
307320 nrot = 32 ; // Must be at least 4, but more increased the uniformity of the produced seeds entropy.
@@ -328,11 +341,9 @@ ISR(WDT_vect) {
328341 seed1 = seed1 ^ TCNT1L;
329342}
330343
331- // Board definitions
344+ // Preprocessor code for identifying microcontroller board
332345#if defined(TEENSYDUINO)
333-
334346// --------------- Teensy -----------------
335-
336347#if defined(__AVR_ATmega32U4__)
337348#define BOARD F (" Teensy 2.0" )
338349#elif defined(__AVR_AT90USB1286__)
@@ -350,9 +361,7 @@ ISR(WDT_vect) {
350361#else
351362#define BOARD F (" Unknown Board" )
352363#endif
353-
354364#else // --------------- Arduino ------------------
355-
356365#if defined(ARDUINO_AVR_ADK)
357366#define BOARD F (" Arduino Mega Adk" )
358367#elif defined(ARDUINO_AVR_BT) // Bluetooth
@@ -406,5 +415,4 @@ ISR(WDT_vect) {
406415#else
407416#define BOARD F (" Unknown Board" )
408417#endif
409-
410418#endif
0 commit comments