WOLL-Y : Wake On LAN Appliance
- 1 Abstract
- 2 The userinterface
- 3 The hardware
- 4 The Configuration data
- 5 The Communication Protocol
- 5.1 The Commands
- 5.2 WOLLY packets
- 6 WOLL-Y firmware
- 7 Debugging tools used
- 8 Possible enhancements
- 9 Attachments
What is 'Wake-On-LAN' ?
Wake on LAN, or WOL - hence the name : WOLL-Y - , is the ability to send a signal over a local area network (LAN) to power up a PC. Perhaps you have a PC at home that you don’t want to leave powered on, yet may need to access while at work. Maybe you want to conserve energy and leave your PC off except when you need it. Certainly, your PC is more secure from hackers when it is off.
The problem definition
A friend of mine had decided to build his own DVD/Harddisk recorder based on a PC with Linux and a TV card. This turned out to be a very cost-effective and future-proof solution that allowed to add many features. However it had also one disadvantage : the PC had to be switched on before the recording would start. Not very powerfriendly. Some experimenting showed that it was possible to turn on the PC using a the 'wake-on-lan' feature in the BIOS. Having one PC switch on another was obviously nonsense, so the idea grew to develop a power-friendly, microcontroller based little appliance that could send a 'Wake-On-Lan' signal to the PC at predefined times. If this worked the PC could be switched on before the recording and then the PC could switch itself back off when the recording was done. A nice idea that turned out to be a little bit more complex than originally anticipated.
The device presented here is based on a microcontroller (PIC 18F458) with an extra ethernet interface. Via this interface the device will receive commands from a host computer. These commands allow the user to specify at which times which computer has to be turned on. WOLL-Y will then issue so called 'Wake-On-Lan' Magic packets at the preset times and send them to the desired computer (identified via its MAC address). To allow WOLLY to determine the time it has a battery backed up real time clock. All configuration is stored in non-volatile RAM (either EEPROM or battery backed up RAM). To allow monitoring of the health state of WOLLY, the device has a status led and will send broadcast UDP packets at preset intervals containing its basic settings.
"Wake On Lan" is not new at all and most PCs have it available in their BIOS settings nowadays. This means a number of possible other applications for WOLLY exist. Sometimes PCs are left running for convenience or out of negligance, but just think of the power you would save if all machines would be shutdown overnight. Savings in electrical power by the machine itself, but also the airco etc... Also think of the safety risk involved when machines are left on ? Shutting down machines is considered a good practice, but sometimes not done out of 'convenience'. WOLLY can bridge the gap between common sense and ease-of-use :
- Wake-On-LAN already exits for a long time in PCs to allow you to boot machines to distribute patches, applications, virus definitions overnight. In a typical situation a server that is continously on could wake up the machines before starting its multicast. However, a server consumes 150-300 W, whereas WOLLY consumes 0.8 Watt.
- In companies a number of machines are typically left running because they have to do an import/export/batch processing overnight. This may take only a few minutes, yet the PC is left running all day and all night. This means that WOLLY could be used more economically to selectively switch on machines if and when needed. In fact, this would even save you when a user accidently switched off the machine, without realizing it needs to do its stuff overnight
- Do you run Windows ? Do you have users complaining it takes ages to boot the machines in the morning despite of the zillian bytes RAM, the quad core - gigahertz processors, the sata disks ? Why not switch them on 15 minutes before the start of the working day ?
- Need to do some reconfiguration in a remote office in a different timezone ? After their workhours ? No problem, just switch on the machine with WOLLY and then take it over using remote desktop software.
The hardware is made as generic as possible. It can be used in any embedded application that requires a network connection :
- Webserver : We built a little application that simply showed the clock and the status of port C on a website and allowed to change the setting of port D. This worked fine. For big & beautiful websites, you would probably have to add an SD Card interface to store the webpages. This is relatively simple to do, since SDCards use SPI to communicate with the host and SPI is on board. An extra EEPROM or a USB interface is of course also possible.
- Domotica system : allowing to monitor the state of your home from anywhere in the world and change settings when needed. Measure and control via the internet. The proof of concept (our little webserver) showed it is not utopia.
- Allow communication between different devices of an embedded systems to create an integrated control system.
Wake On Wan : Wake-On-LAN is by definition limited to the local LAN. This means routers will not forward the WOL packages via the internet (luckily!). It is possible to make this happen and you will find multiple references on how to do that on the internet, but they all mean you have to start changing routers to do port forwarding and/or NAT-ting. Sometimes you are in a remote location (a hotel, a hotspot, a friend, ....) where this is not possible. Well, no problem. WOLLY will send its wake-on-lan's to the local lan only (your machines), but can be reconfigured from anywhere in the world. The only thing required is that you change your own router (which you do control) to let WOLL-Y be accessible from the outside world. Isn't that neat ?
Although we had an LCD attached during development, in the final design it is not present. The entire user interface revolves around one button and 3 LED's. The detailed information is communicated via UDP broadcasts which the host can pick up and integrate in its application. We also created a basic Windows application to get started. Obviously the real advantage will come if the programming of the device is integrated in the 'real' application: in our case, the mediacenter.
The Red, Green, Yellow LED
- When the red led is turned on in the configuration, it will blink every time a heartbeat is sent. However, you can decide to turn of the led all together in the configuration. In this case it will only blink when an error occurred. The heartbeat UDP packages will stilll be sent regardless.
- When an error occurs, the heartbeat is sent continuously (approx. 10 times per second) and the red led blinks like crazy.
- The Green and Yellow led are attached to the Ethernet interface chip. The default setting is that the green led blinks when a package arrive, the yellow led when a packet is sent. However, this can be completely changed to your desire (including turning them off). Chech the configuration section on the settings are.
The user button
- If the button is pressed at power-up, WOLLY will blink the red led 4 x times (regardless of the red led flag)and clear all stored data and performs a factory reset with the predefined default values.
- If the button is pressed during normal operation, WOLLY will blink the LED 4 times (regardless of the red led flag), the most recent error is cleared and a heartbeat packet is sent, returning WOLLY to a 'normal' operational state. This allows you to clear any errors which you already noticed, stop the continuous blinking and sending an additional heartbeat. This would be very useful if the heartbeat rate is set to 5 minutes and you wonder if the device is still alive.
Resetting the device
Resetting is done by power cycling the device. This will not clear any data nor clear any errorsetting. What it will do is reinitialize the device (DHCP detection, reset the deadlock checking, ....)
Typical startup sequence
When the device is booted the red led goes on. Wolly starts reading its configuration data which takes about 4 seconds. After this the Ethernet interface is initialized and the green led goes on. If Wolly is instructed to do DHCP you will see the yellow led blinking a few times. Once the IP configuration is received, the red led is turned off. From that moment on, you will see the red led blinking according to the preset heartbeat rate (default= 10 seconds) if the red led flag is switched on (default = yes). The green and yellow led give you information about the ethernet traffic according to the settings in the configuration file. (default : green=receive / yellow=transmit)
Configuring the device
This is handled via the communication protocol, so check that section for details. The GUI can of course also be used, but you will need to understand the basic protocol to know how to use it.
A GUI for the host PC
Attached you will find a program that allows you to interact with WOLL-Y from your PC. Basically the program will capture the heartbeat packets (you will need to know the heartbeat port) and with the information in it will allow you to communicate with WOLL-Y, allowing you to change the configuration, create new WOL entries and sync the clock. Once you understand the basic functions of the firmware and the protocol used, the rest is pretty self-explaining (see also linux command line interface for a code example)
>> The source code is attached. Everything was developped with Qt4 and GCC, so the software is cross-platform : Windows, Linux, MacOS. You will have to recompile it for your platform though (Windows executable attached)
Command Line interface
Given the fact that the mediacenter was a Linux machine, we decided that the PC software (the GUI) should run on Linux, not on Windows. The software there was written using open source tools : GCC as C compiler + Qt as userinterface. However, this is more a matter of personal flavor and how you are going to use it. What I would like to present here is a simple command line interface which is a little bit more generic and shows how easy it is to reconfigure WOLLY with some simple scripting from within another application. We used it extensively while debugging.
Syntax : writecommand <cmdnr> | nc -u <ipaddress of wolly> <command port of wolly> | readcommand where
- cmdnr = 1...6 to send the respective command. The contents of the dataarea are hardcoded
- ipaddress of wolly is either the DHCP address or fixed address you gave it (default = DHCP)
- commandport of wolly = the portnumber you gave it in the config (default=4001)
>> The source code of writecommand & readcommand is attached
The hardware is as generic as possible so that it can be used for any application that needs an ethernet interface. In fact during testing we used this hardware to compile and run some of the examples that came with the library successfully : a webserver which allowed to change the LEDs on port B and read the buttons of port C, a telnet daemon, .... So this hardware can be used for your own embedded TCP/IP application. Just as an example : we gave our WOLLY a fixed IP address, configured our internet router with port forwarding, used DynDNS to get a dynamic hostname for our internet connection et voila : WOLLY can be configured and read via Internet. Cool, a basis for a domotica system that is controlable from your vacation resort ? Anyhow, this is what we built.
The building blocks
As basic hardware components we decided we needed :
- a microcontroller powerful enough to handle the ethernet traffic : PIC 18F458 (32 K program memory, 1536 bytes of RAM, 256 bytes of EEPROM)
- an ethernet interface chip : Microchip ENC28J60 with SPI interface
- a real-time clock with battery backup to survive powerfailures : DS1307
- some permanent storage room to store configuration parameters and the schedule on when to turn on the PC : the PIC has 256 bytes, the DS1307 56 bytes we can use for this
The circuit we used was based on a design we found in an article called "How-to build a web server for 30 euros !" on Electronicfr.com
However, we made some changes :
- a different PIC was used - the 18F458 - because we had that one available and it has : 32K of ROM, 1536 bytes of RAM and 256 bytes of EEPROM
- we added a LED on PortC.F0 (active when port low)
- a BUTTON was connected on PortC.F1 (goes low when pressed)as 'user button'
- a BUTTON connected between the MCLR pin and ground as 'reset button'
- the DS1307 using software I²C on PortD.F1 for SDA and PORTD.F0 for SCL
- the ENC28J60 uses hardware SPI on standard hardware SPI ports + PORTD.F2 for Reset and PORTD.F3 for chip select
- an HD44780 compatible LCD (2x24) was added for debugging on PORTB : bits 0..3 = D4...D7 / 4 = EN / 5 = RS / 6 = RW
- the 74HTC08 was removed, because it was not needed. The pic will interprete 3.3V as a logic '1' so no need for the extra complexity.
What we didn't do :
- We originally wanted to add a USB interface (with a 18F4550) to have a bootloader via USB, but it turned out we had problems programming the 18F4550 with our pic programmer so we gave up on that idea.
- When we decided USB was not an option, we wanted to add an RS232 interface to program the device (e.g. set the next wakeup time), but we eventually decided this was not needed either. We added the needed code to the ethernet protocol to allow remote programming via ethernet ... and by extension via internet !
The circuit contains some critical components:
- the ethernet connector. The difficult part are the magnetic filters. Our advise is to buy a connector with these filters built-in. It will cost you around 4 euro. If you decide to strip it of an old network card, you should also take the filters of it (looks like an oversized IC with approx. 10-12 pins).
- the ENC28J60 needs to run at 25Mhz. Finding this crystal turned out to be not easy, so we took it from some old network cards we had lying about.
- the four resistors of 49.9 ohm / 1% : these turned out to be relatively easy to find online for a few cents at RS-Components
- the resistor connected to the RBIAS output of the ENC28J60 is dependent on the revision of the chip. It can be different values and is rather critical, since it determines the shape of the ethernet signal. For us it was 2.32 kohm / 1% ... which we didn't have available, so we built it as 2.2 + 1.2 K ohm / 5%. The circuit runs fine with it, but sometimes packages get lost. Maybe because of the deviation ? Other values can be 2.2kohm or 2.7 kohm depending on your revision number. Again, check the revision number of the chip you use. Our was revision B.7. The circuit will work with different values, but maybe unreliable. Maybe we will need to order the correct resistors after all (RS-Components has them)
- If you use an 'old' ENC28J60 chip the speed of the SPI bus is critical. We had rev B.7 and we could select any crystal, but make sure you choose the correct one. The best option is probably to use the clock out signal of the ENC28J60 as clock in for the PIC, since this is guaranteed to work.
The Configuration data
The heart of the system is a network protocol that allows to send commands from the host to WOLLY and allows WOLLY to report back to the host, send out debug information (so called heartbeat) and -most important- allows to send 'wake-on-lan' magic packets to wake up computers on the LAN. The protocol is based on UDP. The basis of the protocol is of course the configuration stored by WOLLY : config data / WOL entries / Errorlog / Clock
Generic formatting information
- Bytes are numbered from starting address + offset
- Bits are numbered from right to left I.e. Bit 7 of byte is masked by 0x80, bit 6 by 0x40 etc...
- 2 byte numbers are stored the low byte in byte 'n' and the high byte in byte 'n+1'
- 4 byte numbers are stored the low byte in byte 'n' to highest byte in byte ‘n+3’
Configuration data : 36 bytes
WOLLY can store up to 36 bytes of configuration data. This data is stored in EEPROM. On first boot -or when pressing the user button during power-on- the configuration is reset to the factory defaults, but with the command 'set config' the host can change the information.
|5-10||MAC address of the device||11:22:33:44:55:66|
|11-14||Default IP address||192.168.1.60|
|15-18||Default subnet mask||255.255.255.0|
|23-26||Default Heartbeat IP address||18.104.22.168|
|27-28||Portnumber to listen to for incoming commands||4001|
|29-30||Portnumber for heartbeat||4002|
|31||Miscellaneous bits :
red LED on + 10 sec heartbeat + try DHCP + automatic daylight saving + try to broadcast
|32||Yellow LED (High nibble) & Green LED (LOW nibble)
Meaning of these Configuration bits 1111 = Reserved 1110 = Duplex status and collision 1101 = Link status+transmit/receive 1100 = Link status+receive activity 1011 = Blink slow 1010 = Blink fast 1001 = Off 1000 = On 0111 = Transmit and receive activity 0110 = Reserved 0101 = Display duplex status 0100 = Display link status 0011 = Display collision activity 0010 = Display receive activity 0001 = Display transmit activity 0000 = Reserved
|35||Used by WOLLY to determine the reason of a reset (read only)||'r' for normal reset|
WOL entries data space : 220 Bytes
Contains 20 WOL entries of 11 bytes each, ordered by nearest in the future first. This order is not very important, since WOLLY will scan all 20 entries each minute. Each entry has the following layout
|0-5||MAC address of the device to wake up. Can be FF:FF:FF:FF:FF:FF to wake up all devices on the LAN|
|6||Year as binary offset since 2000. (0..99 max)|
|7||Bits 7-4 : Repetition factor with a value between 0 and 11
Bits 3-0 : Month (1..12)
|8||Day of month (1..31)|
An entry with MAC address equal to 00:00:00:00:00:00 is considered to be an empty entry. An entry is removed if the date in the WOL entry is the same as the current date.
Error Log : 56 bytes
The error log contains 28 entries of 2 bytes each. Log entries are ordered as most recent error first. I.e. Each time a log entry is used is is removed from its current position and added a the front of the list. When Full, the oldest entry (last in the list) is discarded and the log is shifted.
Each entry has the following format :
|0 : High nibble||Command code|
|0 : Low nibble||Error code|
|1||Number of times the error has occurred|
Existing command-codes :
- WARNING (0x10) : only a warning / not fatal. Typically used when a packet is received on the wrong port or via TCP.
- CMD_DS1307 (0x20) : an internal error when reading/writing the real time clock. Typically a program error
- CMD_DATATABLE (0x30) : an internal error when changing the data tables. Typically a program error.
- CMD_PROCESSCMD (0X40) : is raised when WOLLY detects an error while processing the command. Typically a protocol violation
- CMD_DEADLOCK (0xF0) : is raised when WOLLY is caught in an endless loop and resets itself
Existing Errors :
- ERR_INDEX (0x01) : Index out of range
- ERR_INVALID_FORMAT (0x02) : data format not as agreed
- ERR_WRONG_VERSION (0x03) : During each communication a version number is sent. If this doesn't match the code this error is raised. Typically a mismatch between the firmware and the host software.
- ERR_UNKNOWN_CMD (0x04) : A commandnumber was received that is not supported
- ERR_WRONG_PORT (0x05) : An UDP packet was received, but on the wrong port
- ERR_NO_TCP (0x06) : A TCP packet was received, but TCP is not supported
- ERR_ENDLESS_LOOP (0x0F) : After 20 seconds of no activity, WOLLY resets and raises this error.
Clock Data : 8 bytes
The clock is stored in battery backed up RAM (the DS1307). When written or read the following format is used :
|0||Year as a binary number since 2000 (max. = 99)|
|2||Day of month (1..31)|
|3||Day of week (1= monday ... 7 = sunday)|
|7||Daylight saving : 'w' = wintertime / 's' = summertime / '?' = don't know|
The Communication Protocol
WOLLY is controlled by sending commands as a UDP packet to the device on a predefined port. The layout of these UDP packets is described below.
General Command Format
|0-4||Preamble : the ASCII string "WOLLY"|
|5||Major version number, corresponds to the format of the data structure (currently : 0x02)|
|6||Minor version number, corresponds to the commands supported in the protocol (currently : 0x00)|
|7||Build number, corresponds to the program code's version (currently : 0x01)|
|8||Command : 0-254 from HOST to WOLLY / 255 is reserved for a reply command from WOLLY|
|9||Echo byte (random value sent by HOST to be copied over in reply from WOLLY)|
|10 - 10+n-1||n bytes of data specific to the command|
|10+n - 10+n+1||CRC (not yet used)|
|10+n+2 - 10+n+5||Postamble : the ASCII string 'YLLOW'|
WOLLY responds to every command with a packet in the format of command FF
Command 01 : DUMP
- This command is used to ask the dump all data stored on the device i.e Config + Entries + ErrorLog + Clock
- No data is sent with this command
Command 02 : SET CONFIG
- This command is used to update the 36 config bytes + set the device clock.
- IMPORTANT : As a side effect the device is reset. The permanent data is not reset : wol entries, clock, errorlog are not cleared automatically.
The data contained in the message is as follows :
|0-35||See format of the configuration data for the contents|
|36 -43||8 bytes for time in clock format (see above)|
Command 03 : SET CLOCK
- This command is used to set the device clock.
- Note : if 's' or 'w' is given for the daylight savings byte, that value will be used. If anything else is given, WOLLY will determine autonomously what the daylight savings setting should be (summer between last sunday of March 2:00 am and last Sunday of October 3:00am, winter otherwise)
The data contained in the message is as follows :
|0 - 7||8 bytes for time in clock format (see above)|
Command 04 : SET WOL ENTRIES
- This command is used to update the WOL entry table of the device. The previous table is cleared completely. This means all entries have to be given each time this command is issued
- The data contained in the message contains 220 bytes specifying maximal 20 entries. Entries that are not used are set to all '0'.
- Format of each entry is as specified above.
Command 05 : CLEAR ERRORLOG
- This command is used to clear all errors in the errorLog
- Side effect : the heartbeat will return to the preset speed
Command 06 : CLEAR MOST RECENT ERROR
- This command is used to clear the most recent error in the errorLog. In fact the error is not cleared. A 'no-error' is added to the front and all others are pushed down one entry
- Side effect : the heartbeat will return to the preset speed
Command FF : Reply from WOLLY
This packet is sent by the device as a reply to another command.
The format of the data is :
|0||Command return code (0 indicates success, all others an error)|
|1-2||Command sequence number : Each time the device executes a command, it increments this number to indicate the reception and processing of the received command. Returning this number allows clients to keep track of the reaction of the device (kind of a 'are-you-still-there' message)|
|3-6||Uptime since last reset (in tenths of seconds)|
|6-41||36 bytes of config data (see above)|
|42-57||Actual IP address :
|58-277||220 bytes : WOL entries (see above)|
|278-333||56 bytes : Errorlog (see above)|
|334-341||8 bytes : Current device clock time (see above)|
Next to listening to the command port and replying on requests, WOLLY will also send information out autonomously : heartbeat UDP packets and WOL Magic packets.
This UDP packet is sent to broadcast its current config on a specific port (default : 4002) This config might be invalid (upon power on of the device) but allows clients to detect the config, find out the current IP address and portnumber and initialize the device properly.
You can set the heartbeat rate in the configuration. So this packet will be sent between every 20 msec and every 5 minutes. In case of an error, the heartbeat is sent continuously and the red led will start blinking like crazy (regardless of the red led setting in the config)
So what is sent ?
|0 -4||preamble, ASCII text 'WOLLY')|
|5||Major version number (version of data format)|
|6||Minor version number (version number of command protocol)|
|7||Build number (version number of program code)|
|8||'00' : Heartbeat code|
|9-10||Current command sequence number|
|11-14||Current IP Address of the device|
|15-18||Current Subnet mask of the device|
|19-20||Current Command port the device listens to|
|21-26||Current MAC address of the device|
|83-90||Current time/date & daylight savings|
|91-95||Postamble, ASCII text 'YLLOW'|
WAKE ON LAN Magic Packet
"Wake On LAN" is the name for a technical development jointly created by IBM and Intel. The technology allows "enabled" devices to be powered on remotely via a special type of network communication. A WOL-enabled device must have special hardware, at minimum a special network interface and power circuitry that allows the network interface to signal the device to turn itself on. This has been built in computers for 1 years now, but typically has to be activated in the BIOS. A WOL-enabled device, when powered off, will still draw a tiny amount of electricity to drive the network interface. The interface remains in a passive, listening mode, sending nothing out on the network. To wake up the device, a specially formed packet is sent to the network port where the device is plugged in. This special packet, called a magic packet, carries a special "signature." When the network interface sees this signature, it recognizes this as a wakeup call.
This is the standard Wake-On-Lan magic packet and contains :
|0-5||Destination MAC Address|
|6-11||My own MAC address|
|12-13||"08:42" = Fixed Identifier that this is a WOL command|
|14-19||"FF:FF:FF:FF:FF:FF:FF" = Fixed Identifier|
|20-115||16 times the MAC address of the Destination|
There are no other restrictions on a Magic Packet frame. For instance, the sequence could be in a UDP packet, an IPX packet, etc. WOLL-Y will broadcast its magic packet via UDP on port 9. If you want to switch on machines behind your router, so on the WAN, you will need reconfigure your router so that it forwards these packets to the correct locations on the internet.
The software consists of 2 major parts : the firmware which is in the embedded device and the software which runs on the host (Linux in our case) to control the device. This means : changing configuration, setting the clock, setting the wake-up events or simply reading the status of the device.
The programming environment
We doubted for a long time on which programming environment to use. Initially we wanted to use the free C18 compiler of Microchip, because a free TCP/IP stack implementation is available for the ENC28J60. But eventaully we had to forfit on that because the full TCP/IP stack was too big for our PIC. So we reverted to the (non-free) MikroC compiler that also has a library to communicate with the ENC28J60. It turned out to be good enough for our project, although we had to implement some additional routines to overcome the limitations of the library (e.g. UDP broadcasting and setting the LED configuration)
The firmware logic
At startup, WOLL-Y would ask its IPadress from a DHCP server and then start broadcasting its internal settings on the local LAN. A 'host PC' would pick up this configuration broadcast and use the information it it (like its actual IP address) to start sending commands to WOLL-Y. The basic commands needed was a table of dates & times on when to wake up which machine. A machine is uniquely identified with its MAC address. A little calculation showed that one entry would be : 6 bytes for the mac address + 2.5 for the date (day=byte / month = nibble / year = byte) + 2 bytes for time (hr:min) + half a byte for a repetition factor (every day, on a given weekday, ....) = 11 bytes in total. This meant our WOL-Y could store 256/11 = 20 entries, leaving 36 configuration bytes and 56 bytes for the errorlog in permanent storage. Simple right ?
This is the high level algorithm :
INITIALISATION : Initialise all PIC registers Initialise the timer interrupt Start initialisation of WOLLY - Turn RED LED on - Initialise LCD screen - Initialise I²C in software - Initialise the Realt Time Clock (DS1307) - If the user button pressed ? Yes : Blink Red led 4x fast & perform a factory reset of the configuration settings No : Read the Configuration from EEPROM (If the header is not valid, do a factory reset) - Did we restart because of an endless loop (deadlock error) ? Yes : Add error 'ENDLESS LOOP' to the errorlog - Set the heartbeat from the config file - Initialise the ENC28J60 - if the DHCP flag is set, try to obtain an IP address (60 seconds timeout). If not, set a fixed IP as in the config - Set the green & yellow led of the ENC28J60 according to the config - Turn the RED LED off
MAIN LOOP : - Is the userbutton pressed ? If yes, clear the most recent error and blink RED Led 4x fast to acknowledge - Did our DHCP lease expire ? If yes, renew the DHCP address - Read the clockinfo (DS1307) - Do we need to switch from summer to winter or from winter to summer ? - Update the LCD screen (clock, IP address, portnumber, command nb, last error) - Did we receive an UDP packet on the correct port ? If yes, process the command. Command 1 : nothing to do, but a valid command (just to reply) Command 2 : overwrite config data in EEPROM, set clock and flag for reboot Command 3 : set clock Command 4 : overwrite WOL entries Command 5 : Clear Errorlog and reset blinking of RED led to normal speed Command 6 : Clear most recent error and reset red led to normal speed. - Send answer to the host (= command FF) - Do we need to reboot (with set config command) ? Force reboot, but no deadlock error. - Did an error occur ? YES : Blink RED Led and send heartbeat NO : Is it time to send a Heartbeat ? if yes, send one and blink red led if flag is set. - Are we at a new minute? If yes, Check each WOL entry * If MAC==00:00:00:00:00:00 then skip this entry * If hour & min match then check if repetition matches with weekday or date * If match then send a WOL packet to the MAC address * if date == current date then delete the entry - Reset Deadlock END MAIN LOOP
INTERRUPT ROUTINE for TIMER OVERFLOW : (625 Herz) - Increase counter - if counter == 62 then increase 'tenths of a second' counter - if counter == 625 then * increase 'second' counter (used by ENC28J60 library) * if deadlock counter > 20 seconds then perform a RESET - Re-enable Timer interrupt
Note : we couldn't use the standard watchdoc timer of the PIC, because it allows to reset between 18.2 msec and 2 seconds which is too fast (because som e library routines don't return fast enough like DHCP), so we implemented one ourselves with interrupts which resets after 20 seconds.
Debugging tools used
- The hardware debugging was done with a simple volt-meter and a lot of patience.
- The protocol debugging was done using Wireshark, a darn good protocol analyzer. This saved us a lot of grievance
- netcat (nc) allowed us to send packages from the commandline and test the firmware independantly.
- The firmware debugging was done by writing the software in little blocks and testing each as we went along.
- The LCD proved to be invaluable to give some feedback on where we were and what was going on
- Simple code (re)reading and lots of coffee were needed.
- The host software was debugged with gdb, patience and Coca-Cola Zero.
Three basic tips :
- Read the datasheets thoroughly and frequently.
- 'Assumptions' are your worst enemy. Assumptions about the hardware, assumptions about the compiler, assumptions about the result of some library functions, assumptions about byteorder, assumptions on what you receive from the other side, assumptions about the state of the coffee pot.
- Read the datasheets again.
- Looking back at the project we should have selected a low power PIC. The one we choose runs at 5V, whereas the ENC28J60 needs 3.3Volts, so we needed a dual powersuppply. It would have been more logic to select all 3.3 volt components.
- If you want to use the C18 compiler and the TCP/IP stack, make sure your PIC has ample space. 32K is simply not enough ! An option would have been to start stripping the code and take all unneeded protocols. Our firmware only needs data link layer and UDP protocols. All the rest can be stripped. However, this is not for the people with a weak heart :-) It is a lot easier to select one with 64K of program memory (e.g. 18F4620 which seems pin-compatible with the 18F458)
- The powerconsumption of the entire system is around 160 mA. Not much, but also not negligable. In a future version we would select a real time clock that has an alarm function which would allow us to put the entire circuit to sleep and wake it up just before the next event. The DS1306 has this capability, but we couldn't use it since it works with SPI (just like the ENC28J60), but with a different mode. It is not allowed to mix differnet SPI modes on the same SPI interface. So we would have had to either select a PIC with 2 SPI interface or use the soft library for SPI communication. We decided not to do this and use the DS1307 with I²C. However, this would have been an nice additional feature to save power. On the other hand it would also have added an additional complexity, because we would have had to also implement Wake-on-LAN for the ENC28J60 itself to restart the PIC when a package arrives for WOLL-Y. So, a wake -on-lan for a wake-on-lan server sort of speak :-) Let us know if someone decides to implement this.