├── README.md └── eth-bootloader ├── bootloader client ├── Recv.java └── Send.java └── firmware ├── Makefile ├── Readme.txt ├── Test list.txt ├── announce.c ├── app.c ├── bigapp.c ├── debug.c ├── debug.h ├── main.c ├── main.h ├── net.c ├── net.h ├── neteeprom.h ├── settings.c ├── tftp.c ├── tftp.h ├── validate.c ├── validate.h └── w5100_reg.h /README.md: -------------------------------------------------------------------------------- 1 | Ethernet Bootloader 2 | ================== 3 | 4 | Arduino Ethernet board and TFTP Bootloader 5 | ========================================== 6 | 7 | This is an unfinished TFTP bootloader for the Arduino Ethernet. The developer that was hired to write it never finished it so we are opening it up to the community in the hope that somebody will fix it and make it work. 8 | 9 | It was originally designed to run on both the Arduino Ethernet board and a regular Arduino with Ethernet Shield. 10 | 11 | If you intend to work on it, join the Arduino Developers mailing list and let us know. 12 | 13 | 16 July 2011 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /eth-bootloader/bootloader client/Recv.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | import java.net.DatagramPacket; 3 | import java.net.DatagramSocket; 4 | import java.net.SocketException; 5 | 6 | public class Recv { 7 | 8 | public static void main(String[] args) { 9 | if (args.length != 1) { 10 | System.out.println("Please specify receive port"); 11 | System.out.println("Recv "); 12 | System.exit(1); 13 | } 14 | int port = Integer.parseInt(args[0]); 15 | recv(port); 16 | } 17 | 18 | public static void recv(int port) { 19 | try { 20 | byte[] buf = new byte[256]; 21 | DatagramSocket socket = new DatagramSocket(port); 22 | DatagramPacket pack = new DatagramPacket(buf, buf.length); 23 | System.out.println("Listening on UDP port 5555."); 24 | System.out.println("Waiting for packets..."); 25 | socket.receive(pack); 26 | 27 | // display response 28 | String received = new String(pack.getData(), 0, pack.getLength()); 29 | System.out.println("Received: " + received); 30 | socket.close(); 31 | } catch (SocketException e) { 32 | e.printStackTrace(); 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /eth-bootloader/bootloader client/Send.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | import java.net.DatagramPacket; 3 | import java.net.DatagramSocket; 4 | import java.net.InetAddress; 5 | import java.net.SocketException; 6 | import java.net.UnknownHostException; 7 | 8 | public class Send { 9 | 10 | public static void main(String[] args) { 11 | if (args.length != 2) { 12 | System.out.println("Please specify send address and port"); 13 | System.out.println("Send "); 14 | System.exit(1); 15 | } 16 | try { 17 | InetAddress address = InetAddress.getByName(args[0]); 18 | int port = Integer.parseInt(args[1]); 19 | send(address, port); 20 | } catch (UnknownHostException e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | 25 | public static void send(InetAddress _addr, int _port) { 26 | 27 | try { 28 | byte[] magic = { 'a', 'r', 'd', 'u', 'i', 'n', 'o' }; 29 | DatagramPacket packet; 30 | packet = new DatagramPacket(magic, magic.length, _addr, _port); 31 | 32 | DatagramSocket socket = new DatagramSocket(); 33 | socket.send(packet); 34 | socket.close(); 35 | System.out.println("Packet sent."); 36 | } catch (SocketException e) { 37 | e.printStackTrace(); 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/Makefile: -------------------------------------------------------------------------------- 1 | # Name: tftp.c 2 | # Author: . 3 | # Copyright: Arduino 4 | # License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | # Project: eboot 6 | # Function: tftp implementation and flasher 7 | # Version: 0.1 tftp / flashing functional 8 | 9 | # Important make targets: 10 | # install : flash bootloader using AVR ISP MkII 11 | # disasm : output disassembly of bootloader 12 | # test : flash bootloader, then upload an app over tftp 13 | # readback : read back flash contents to read.hex 14 | # testsequence: install bootloader, upload app and read back flash 15 | 16 | DEVICE = atmega328p 17 | CLOCK = 16000000 18 | PROGRAMMER = -c avrispmkII -P usb 19 | OBJECTS = main.o net.o tftp.o validate.o announce.o 20 | APPOBJECTS = app.o 21 | 22 | # 2Kword boot block 23 | FUSES = -U efuse:w:0x05:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m 24 | LDFLAGS = -Ttext=0x7000 25 | 26 | # 1Kword boot block 27 | #FUSES = -U efuse:w:0x05:m -U hfuse:w:0xda:m -U lfuse:w:0xff:m 28 | #LDFLAGS = -Ttext=0x7800 29 | 30 | # 512 word boot block 31 | #FUSES = -U efuse:w:0x05:m -U hfuse:w:0xdc:m -U lfuse:w:0xff:m 32 | #LDFLAGS = -Ttext=0x7C00 33 | 34 | # 256 word boot block 35 | #FUSES = -U efuse:w:0x05:m -U hfuse:w:0xde:m -U lfuse:w:0xff:m 36 | #LDFLAGS = -Ttext=0x7E00 37 | 38 | # Extended Fuse Byte: 39 | # 0x05 = 0 0 0 0 0 1 0 1 40 | # \---+---/ \-+-/ 41 | # | +------ BODLEVEL Brownout detect at 2.5 to 2.9V 42 | # +-------------- Unused 43 | # 44 | # High Fuse Byte: 45 | # 0xD8 = 1 1 0 1 1 0 0 0 <-- BOOTRST Reset to bootloader 46 | # ^ ^ ^ ^ ^ \+/ 47 | # | | | | | +------- BOOTSZ 2Kword bootloader, 0x3800-0x3FFF, reset at 0x3800 48 | # | | | | +---------- EESAVE EEPROM erased in chip erase 49 | # | | | +------------ WDTON Watchdog timer off 50 | # | | +-------------- SPIEN SPI programming enabled 51 | # | +---------------- DWEN DebugWIRE disabled 52 | # +------------------ RSTDISBL External Reset enabled 53 | # 54 | # Low Fuse Byte: 55 | # 0xFF = 1 1 1 1 1 1 1 1 56 | # | | \+/ \--+--/ 57 | # | | | +------- CKSEL Low power crystal, 16Kck delay 58 | # | | +------------- SUT 65ms delay 59 | # | +---------------- CKOUT No clock out 60 | # +------------------ CKDIV8 No divide by 8 prescaler 61 | 62 | AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) 63 | 64 | # Compiler options to shrink bootloader size 65 | # 66 | CCOPT = -Os 67 | CCOPT += -mno-interrupts 68 | CCOPT += -mshort-calls 69 | CCOPT += -fno-inline-small-functions 70 | CCOPT += -fno-split-wide-types 71 | CCOPT += -Wl,--relax 72 | CCOPT += -nostartfiles 73 | 74 | # These optimisations have no effect, so turned off 75 | # 76 | #CCOPT += -mtiny-stack 77 | #CCOPT += -ffreestanding 78 | #CCOPT += -fpack-struct 79 | #CCOPT += -fno-jump-tables 80 | 81 | COMPILE = avr-gcc -Wall $(CCOPT) -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) 82 | OBJCOPY = avr-objcopy 83 | OBJDUMP = avr-objdump 84 | 85 | # symbolic targets: 86 | all: main.hex app.bin bigapp.bin settings.bin 87 | 88 | %.o: %.c 89 | $(COMPILE) -c $< -o $@ 90 | 91 | %.o: %.S 92 | $(COMPILE) -x assembler-with-cpp -c $< -o $@ 93 | # "-x assembler-with-cpp" should not be necessary since this is the default 94 | # file type for the .S (with capital S) extension. However, upper case 95 | # characters are not always preserved on Windows. To ensure WinAVR 96 | # compatibility define the file type manually. 97 | 98 | %.s: %.c 99 | $(COMPILE) -S $< -o $@ 100 | 101 | %.bin: %.elf 102 | rm -f $@ 103 | $(OBJCOPY) -j .text -j .data -O binary $< $@ 104 | 105 | %.hex: %.elf 106 | rm -f $@ 107 | $(OBJCOPY) -j .text -j .data -O ihex $< $@ 108 | 109 | # Programming targets - which are set up for an AVR ISP MkII USB programmer 110 | flash: main.hex 111 | $(AVRDUDE) -U flash:w:main.hex:i 112 | 113 | fuse: 114 | $(AVRDUDE) $(FUSES) 115 | 116 | # Xcode uses the Makefile targets "", "clean" and "install" 117 | install: flash fuse 118 | 119 | clean: 120 | rm -f *.hex *.elf *.bin 121 | 122 | # Bootloader 123 | # 124 | main.elf: $(OBJECTS) 125 | $(COMPILE) -o main.elf $(OBJECTS) $(LDFLAGS) 126 | 127 | # Small test app - fits in a single packet 128 | # 129 | app.elf: app.o 130 | $(COMPILE) -o app.elf app.o 131 | 132 | # Large test app - fills most of the flash 133 | # 134 | bigapp.elf: bigapp.o 135 | $(COMPILE) -o bigapp.elf bigapp.o 136 | 137 | # Change settings 138 | # 139 | settings.elf: settings.o 140 | $(COMPILE) -o settings.elf settings.o 141 | 142 | 143 | # Targets for code debugging and analysis: 144 | disasm: main.elf 145 | $(OBJDUMP) -d main.elf 146 | 147 | map: main.elf 148 | $(OBJDUMP) -h main.elf 149 | 150 | cpp: 151 | $(COMPILE) -E main.c 152 | 153 | test: install app.bin 154 | sleep 3 155 | echo "put app.bin\nquit\n" | tftp -e 192.168.1.250 156 | 157 | readback: 158 | $(AVRDUDE) -U flash:r:read.hex:i 159 | 160 | testsequence: clean test readback 161 | 162 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/Readme.txt: -------------------------------------------------------------------------------- 1 | Name: Readme.txt 2 | Author: 3 | Copyright: Arduino 4 | License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | Project: eboot 6 | Function: Project documentation 7 | Version: 0.1 tftp / flashing functional 8 | 9 | Ethernet bootloader for the ATmega328P / W5100 10 | 11 | Flashing bootloader: 12 | -------------------- 13 | Connect an AVR ISP MkII and "make install". 14 | 15 | Configuring your network: 16 | ------------------------- 17 | The bootloader default address is 192.168.1.250. 18 | Configure your computer network card to a static address of 192.168.1.1 with a subnet of 255.255.255.0. 19 | By default, the bootloader assumes an internet gateway is at address 192.168.1.1. 20 | 21 | Converting firmware to the right format: 22 | ---------------------------------------- 23 | The bootloader accepts raw binary images, starting at address 0x0000. 24 | These can be generated using avr-objcopy, part of WinAVR / AVR-GCC, using the "-O binary" option. 25 | Example: avr-objcopy -j .text -j .data -O binary app.elf app.bin 26 | 27 | Uploading firmware manually: 28 | ---------------------------- 29 | 1) Check the target board is powered, and connected to the computer ethernet. 30 | 2) Verify the computer network settings: Static IP of 192.168.1.1, Subnet of 255.255.255.0. 31 | 3) Push reset button to start the bootloader. The LED will blink rapidly. 32 | 4) In a console window: tftp -e 192.168.1.250 33 | 5) At the tftp> prompt: put app.bin (where app.bin is your application binary image) 34 | 6) The board will be reprogrammed. Type quit to exit tftp. 35 | 36 | Flash codes: 37 | ------------ 38 | Rapid blinking: Ethernet bootloader is running. 39 | Slow fading: Test application is running. 40 | 41 | 42 | Version history 43 | --------------- 44 | 0.1: First internal release. Supports uploads on tftp. 45 | 46 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/Test list.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/TFTP-Bootloader/3fd2b7f70d6b0957b2d569ba4d22632fc78c617e/eth-bootloader/firmware/Test list.txt -------------------------------------------------------------------------------- /eth-bootloader/firmware/announce.c: -------------------------------------------------------------------------------- 1 | /* Name: announce.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Function: announcement (Network broadcast) 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "net.h" 15 | #include "w5100_reg.h" 16 | #include "tftp.h" 17 | #include "main.h" 18 | #include "validate.h" 19 | #include "debug.h" 20 | 21 | uint16_t readPointer; 22 | 23 | #define ANNOUNCE_PORT (5555) 24 | #define ANNOUNCE_DATA_SIZE 128 25 | 26 | char *hex="0123456789ABCDEF"; 27 | 28 | char bootloaderIdentString[] PROGMEM = "Ethernet 1.0"; 29 | #define bootloaderIdentStringLength (12) 30 | 31 | uint8_t readNextByte() { 32 | uint8_t returnValue; 33 | returnValue = readPointer++; 34 | if (readPointer == S2_RX_END) readPointer = S2_RX_START; 35 | return returnValue; 36 | } 37 | 38 | void announceReply() { 39 | uint8_t txBuffer[100]; 40 | uint8_t *txPtr; 41 | uint8_t packetLength = 0; 42 | uint16_t writePointer; 43 | uint8_t value; 44 | uint8_t i; 45 | 46 | writePointer = netReadWord(REG_S2_TX_WR0) + S2_TX_START; 47 | txPtr = txBuffer + 2; 48 | 49 | // Send IP address in hex 50 | // 51 | for (i=REG_SIPR0; i<=REG_SIPR3; i++) { 52 | value = netReadReg(i); 53 | *txPtr++ = hex[value>>4]; 54 | *txPtr++ = hex[value & 0xf]; 55 | } 56 | // 57 | // Tag on ident string 58 | // 59 | memcpy_P(txPtr,bootloaderIdentString,bootloaderIdentStringLength); 60 | packetLength = 8 + bootloaderIdentStringLength; 61 | 62 | // Write packet length at start of packet 63 | txBuffer[0] = 0; 64 | txBuffer[1] = packetLength; 65 | packetLength += 2; 66 | txPtr = txBuffer; 67 | while (packetLength--) { 68 | netWriteReg(writePointer++, *txPtr++); 69 | if (writePointer == S2_TX_END) writePointer = S2_TX_START; 70 | } 71 | netWriteWord(REG_S2_TX_WR0, writePointer - S2_TX_START); 72 | netWriteReg(REG_S2_CR,CR_SEND); 73 | while (netReadReg(REG_S2_CR)); 74 | } 75 | 76 | void announcePacket(uint16_t packetSize) { 77 | uint8_t buffer[ANNOUNCE_DATA_SIZE]; 78 | uint16_t packetLength; 79 | 80 | // Transfer entire packet to RAM 81 | uint8_t* bufPtr = buffer; 82 | uint16_t count; 83 | 84 | readPointer = netReadWord(REG_S2_RX_RD0) + S2_RX_START; 85 | 86 | // Read destination IP address 87 | for (count = 0; count<4; count++) { 88 | netWriteReg(REG_S2_DIPR0+count,readNextByte()); 89 | } 90 | 91 | // Read destination port - but ignore it and respond on 5555 anyway. 92 | readNextByte(); 93 | readNextByte(); 94 | netWriteWord(REG_S2_DPORT0, ANNOUNCE_PORT); 95 | 96 | // Read packet length 97 | packetLength = readNextByte() | (readNextByte()<<8); 98 | 99 | // Trim overlong packets 100 | if (packetLength > ANNOUNCE_DATA_SIZE) packetLength = ANNOUNCE_DATA_SIZE; 101 | for (count=packetLength; --count;) { 102 | *bufPtr++ = readNextByte(); 103 | } 104 | netWriteWord(REG_S2_RX_RD0,readPointer - S2_RX_START); // Write back new pointer 105 | netWriteWord(REG_S2_CR, CR_RECV); // Receive again 106 | 107 | // Dump packet 108 | bufPtr = buffer; 109 | 110 | // Parse packet 111 | if (memcmp(buffer,"arduino",7)==0) announceReply(); 112 | } 113 | 114 | void announceInit() { 115 | // Open socket 116 | do { 117 | netWriteWord(REG_S2_PORT0,ANNOUNCE_PORT); 118 | netWriteReg(REG_S2_MR,MR_UDP); 119 | netWriteReg(REG_S2_CR,CR_OPEN); 120 | if (netReadReg(REG_S2_SR) != SOCK_UDP) 121 | netWriteReg(REG_S2_CR,CR_CLOSE); 122 | } while (netReadReg(REG_S2_SR) != SOCK_UDP); 123 | } 124 | 125 | void announcePoll() { 126 | uint16_t packetSize = netReadWord(REG_S2_RX_RSR0); 127 | if (packetSize) { 128 | announcePacket(packetSize); 129 | netWriteReg(REG_S2_CR,CR_CLOSE); 130 | announceInit(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/app.c: -------------------------------------------------------------------------------- 1 | /* Name: app.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Function: Test app for bootloader 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | int main(void) { 14 | uint8_t a,b,c; 15 | DDRB = _BV(5); 16 | for(;;) { 17 | for (a=0; a<255; a++) { 18 | for (c=0; c<15; c++) { 19 | for (b=0; b<255; b++) { 20 | if (ab) PORTB |= _BV(5); 29 | else PORTB &= ~_BV(5); 30 | } 31 | } 32 | } 33 | } 34 | return 0; /* never reached */ 35 | } 36 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/bigapp.c: -------------------------------------------------------------------------------- 1 | /* Name: bigapp.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Function: Test big app for bootloader 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | prog_char dummy[28000] PROGMEM = {}; 15 | 16 | int main(void) { 17 | uint8_t a,b,c; 18 | DDRB = _BV(5); 19 | for(;;) { 20 | for (a=0; a<255; a++) { 21 | for (c=0; c<15; c++) { 22 | for (b=0; b<255; b++) { 23 | if (ab) PORTB |= _BV(5); 32 | else PORTB &= ~_BV(5); 33 | } 34 | } 35 | } 36 | } 37 | return 0; /* never reached */ 38 | } 39 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/debug.c: -------------------------------------------------------------------------------- 1 | /* Name: debug.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Function: Utility routines for bootloader debugging 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | #include "debug.h" 11 | 12 | #ifdef DEBUG 13 | void debugInit() { 14 | UCSR0A = 0x22; 15 | UCSR0B = 0x08; 16 | //UCSR0C = 0x06; // = reset state 17 | UBRR0 = 16; // 115k2 baud 8N1 18 | DDRD = 0x92; 19 | } 20 | void trace(char* msg) { 21 | uint8_t c; 22 | while ((c = *msg++)) { 23 | UDR0 = c; 24 | while (!(UCSR0A & _BV(UDRE0))); 25 | } 26 | } 27 | void putchar(uint8_t c) { 28 | UDR0=c; 29 | while(!(UCSR0A & _BV(UDRE0))); 30 | } 31 | void puthex(uint8_t c) { 32 | c &= 0xf; 33 | if (c>9) c+=7; 34 | UDR0=c+'0'; 35 | while(!(UCSR0A & _BV(UDRE0))); 36 | } 37 | void tracenum(uint16_t num) { 38 | putchar('0'); 39 | putchar('x'); 40 | puthex(num>>12); 41 | puthex(num>>8); 42 | puthex(num>>4); 43 | puthex(num); 44 | } 45 | #else 46 | void debugInit() { 47 | ; 48 | } 49 | #endif 50 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/debug.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //#define DEBUG 5 | 6 | #ifdef DEBUG 7 | #define TRACE(msg) trace(msg) 8 | void trace(char* msg); 9 | void puthex(uint8_t c); 10 | void tracenum(uint16_t num); 11 | #else 12 | #define TRACE(msg) 13 | #endif 14 | void debugInit(); 15 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/main.c: -------------------------------------------------------------------------------- 1 | /* Name: main.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Function: Bootloader core 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | 11 | #include "main.h" 12 | #include "net.h" 13 | #include "tftp.h" 14 | #include 15 | //#include "debug.h" 16 | 17 | uint16_t lastTimer1; 18 | uint16_t tick = 0; 19 | 20 | #define TIMEOUT 3 21 | 22 | int main(void) __attribute__ ((naked)) __attribute__ ((section (".init9"))); 23 | 24 | 25 | // Function 26 | void (*app_start)(void) = 0x0000; 27 | 28 | void updateLed() { 29 | uint16_t nextTimer1 = TCNT1; 30 | if (nextTimer1 & 0x400) PORTB |= _BV(LED_PIN); 31 | else PORTB &= ~_BV(LED_PIN); 32 | if (nextTimer1 < lastTimer1) tick++; 33 | lastTimer1 = nextTimer1; 34 | } 35 | 36 | uint8_t timedOut() { 37 | // Never timeout if there is no code in Flash 38 | if (pgm_read_word(0x0000) == 0xFFFF) return 0; 39 | if (tick > TIMEOUT) return 1; 40 | return 0; 41 | } 42 | 43 | int main(void) { 44 | // cli(); 45 | // SP=RAMEND; // This is done by hardware reset 46 | // asm volatile ("clr __zero_reg__"); 47 | 48 | // Set up outputs to communicate with W5100 chip 49 | DDRB = _BV(SCK_PIN) | _BV(MOSI_PIN) | _BV(SS_PIN); 50 | PORTB = _BV(SCK_PIN) | _BV(MISO_PIN) | _BV(MOSI_PIN) | _BV(SS_PIN); 51 | 52 | // Set up Timer 1 as timekeeper for LED flashing 53 | TCCR1B = 0x05; 54 | SPSR = (1< 2 | #include 3 | #define LED_PIN 5 4 | 5 | void updateLed(); 6 | uint8_t timedOut(); -------------------------------------------------------------------------------- /eth-bootloader/firmware/net.c: -------------------------------------------------------------------------------- 1 | /* Name: net.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Network and W5100 chip support 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | 11 | #include "net.h" 12 | #include "main.h" 13 | //#include "debug.h" 14 | #include "neteeprom.h" 15 | 16 | #define REGISTER_BLOCK_SIZE 28 17 | 18 | uint8_t registerBuffer[REGISTER_BLOCK_SIZE] = { 19 | 0x80, // MR Mode - reset device 20 | 21 | // EEPROM block starts here 22 | 192,168,1,1, // GWR Gateway IP Address Register 23 | 255,255,255,0, // SUBR Subnet Mask Register 24 | 0x12,0x34,0x45,0x78,0x9A,0xBC, // SHAR Source Hardware Address Register 25 | 192,168,1,250, // SIPR Source IP Address Register 26 | // EEPROM block ends here 27 | 28 | 0,0, // Reserved locations 29 | 0, // IR Interrupt Register 30 | 0, // IMR Interrupt Mask Register 31 | 0x07,0xd0, // RTR Retry Time-value Register 32 | 0x80, // RCR Retry Count Register 33 | 0x55, // RMSR Rx Memory Size Register 34 | 0x55 // TMSR Tx Memory Size Register 35 | }; 36 | 37 | void netWriteReg(uint16_t address, uint8_t value) { 38 | SPCR = _BV(SPE) | _BV(MSTR); 39 | SS_LOW(); 40 | SPDR = SPI_WRITE; while(!(SPSR & _BV(SPIF))); 41 | SPDR = address >> 8; while(!(SPSR & _BV(SPIF))); 42 | SPDR = address & 0xff; while(!(SPSR & _BV(SPIF))); 43 | SPDR = value; while(!(SPSR & _BV(SPIF))); 44 | SS_HIGH(); 45 | SPCR = 0; 46 | } 47 | 48 | uint8_t netReadReg(uint16_t address) { 49 | uint8_t returnValue; 50 | SPCR = _BV(SPE) | _BV(MSTR); 51 | SS_LOW(); 52 | SPDR = SPI_READ; while(!(SPSR & _BV(SPIF))); 53 | SPDR = address >> 8; while(!(SPSR & _BV(SPIF))); 54 | SPDR = address & 0xff; while(!(SPSR & _BV(SPIF))); 55 | SPDR = 0; while(!(SPSR & _BV(SPIF))); 56 | SS_HIGH(); 57 | returnValue = SPDR; 58 | SPCR = 0; 59 | return returnValue; 60 | } 61 | uint16_t netReadWord(uint16_t address) { 62 | return (netReadReg(address++)<<8) | netReadReg(address); 63 | } 64 | void netWriteWord(uint16_t address, uint16_t value) { 65 | netWriteReg(address++, value >> 8); 66 | netWriteReg(address, value & 0xff); 67 | } 68 | 69 | void netInit() { 70 | // Set up SPI 71 | 72 | // Pull in altered presets if available 73 | if ( 74 | (eeprom_read_byte(EEPROM_SIG_1) == EEPROM_SIG_1_VALUE) 75 | && (eeprom_read_byte(EEPROM_SIG_2) == EEPROM_SIG_2_VALUE) 76 | ) { 77 | uint8_t i=0; 78 | //TRACE("Using EEPROM settings\n"); 79 | for (;i<18; i++) registerBuffer[i+1] = eeprom_read_byte(EEPROM_DATA+i); 80 | } else { 81 | //TRACE("Using 192.168.1.250\n"); 82 | ; 83 | } 84 | 85 | // Configure Wiznet chip 86 | uint8_t i=0; 87 | for (; i 2 | #include 3 | 4 | #define SCK_PIN 5 5 | #define MISO_PIN 4 6 | #define MOSI_PIN 3 7 | #define SS_PIN 2 8 | 9 | #define EEPROM_SIG_1 ((uint8_t*)0) 10 | #define EEPROM_SIG_2 ((uint8_t*)1) 11 | #define EEPROM_DATA ((uint8_t*)2) 12 | #define EEPROM_SIG_1_VALUE (0x55) 13 | #define EEPROM_SIG_2_VALUE (0xAA) 14 | 15 | void netWriteReg(uint16_t address, uint8_t value); 16 | uint8_t netReadReg(uint16_t address); 17 | uint16_t netReadWord(uint16_t address); 18 | void netWriteWord(uint16_t address, uint16_t value); 19 | 20 | void netInit(); 21 | 22 | #define SS_LOW() PORTB &= ~_BV(SS_PIN) 23 | #define SS_HIGH() PORTB |= _BV(SS_PIN) 24 | 25 | #define SPI_WRITE (0xF0) 26 | #define SPI_READ (0x0F) 27 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/neteeprom.h: -------------------------------------------------------------------------------- 1 | #define EEPROM_SIG_1 ((uint8_t*)0) 2 | #define EEPROM_SIG_2 ((uint8_t*)1) 3 | #define EEPROM_DATA ((uint8_t*)2) 4 | #define EEPROM_GATEWAY ((uint8_t*)2) 5 | #define EEPROM_MAC ((uint8_t*)6) 6 | #define EEPROM_IP ((uint8_t*)12) 7 | 8 | #define EEPROM_SIG_1_VALUE (0x55) 9 | #define EEPROM_SIG_2_VALUE (0xAA) -------------------------------------------------------------------------------- /eth-bootloader/firmware/settings.c: -------------------------------------------------------------------------------- 1 | /* Name: settings.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Function: Alter network EEPROM settings 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include "neteeprom.h" 14 | 15 | /* Alter these to your network setting */ 16 | uint8_t ip_address[4] = {192, 168, 1, 250}; 17 | uint8_t gateway_address[4]= {192, 168, 1, 1}; 18 | uint8_t subnet_mask[4] = {255, 255, 255, 0}; 19 | 20 | uint8_t getRandom() { 21 | uint8_t result = 0; 22 | uint8_t i; 23 | for (i=8; i--;) { 24 | uint8_t bit = 0; 25 | uint8_t dummy; 26 | uint16_t j; 27 | ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 28 | ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1); 29 | ADCSRB = 0; 30 | for (j=1000; i--;) { 31 | ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADPS2) | _BV(ADPS1); 32 | while(ADCSRA & _BV(ADSC)); 33 | bit ^= ADCL; 34 | dummy = ADCH; // ADC result is locked until ADCH is read 35 | } 36 | bit &= 1; 37 | result += result + bit; 38 | } 39 | return result; 40 | } 41 | 42 | int main(void) { 43 | uint8_t mac[6]; 44 | uint8_t i; 45 | 46 | // Deliberately corrupt network settings 47 | eeprom_write_byte(EEPROM_SIG_2,EEPROM_SIG_1_VALUE); 48 | 49 | // Write gateway 50 | for (i=0; i<4; i++) eeprom_write_byte(EEPROM_GATEWAY+i,gateway_address[i]); 51 | 52 | // Write a random MAC address 53 | for (i=0; i<6; i++) eeprom_write_byte(EEPROM_MAC+i,getRandom()); 54 | 55 | // Write IP address 56 | for (i=0; i<4; i++) eeprom_write_byte(EEPROM_IP+i,ip_address[i]); 57 | 58 | // Fix signature bytes 59 | eeprom_write_byte(EEPROM_SIG_1,EEPROM_SIG_1_VALUE); 60 | eeprom_write_byte(EEPROM_SIG_2,EEPROM_SIG_2_VALUE); 61 | 62 | // Stop 63 | while(1); 64 | } 65 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/tftp.c: -------------------------------------------------------------------------------- 1 | /* Name: tftp.c 2 | * Author: . 3 | * Copyright: Arduino 4 | * License: GPL http://www.gnu.org/licenses/gpl-2.0.html 5 | * Project: eboot 6 | * Function: tftp implementation and flasher 7 | * Version: 0.1 tftp / flashing functional 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include "net.h" 14 | #include "w5100_reg.h" 15 | #include "tftp.h" 16 | #include "main.h" 17 | #include "validate.h" 18 | 19 | //#include "debug.h" 20 | 21 | 22 | 23 | // TFTP message types 24 | #define ERROR_UNKNOWN 0 25 | #define ERROR_INVALID 1 26 | #define ACK 2 27 | #define ERROR_FULL 3 28 | #define FINAL_ACK 4 // Like an ACK, but for the final data packet. 29 | #define INVALID_IMAGE 5 30 | 31 | #define TFTP_DATA_SIZE 512 32 | 33 | #define MAX_ADDR 0x7000 // For 328 with 1Kword bootloader 34 | 35 | #define TFTP_HEADER_SIZE 12 36 | #define TFTP_OPCODE_SIZE 2 37 | #define TFTP_BLOCKNO_SIZE 2 38 | #define TFTP_MAX_PAYLOAD 512 39 | #define TFTP_PACKET_MAX_SIZE ( TFTP_HEADER_SIZE + TFTP_OPCODE_SIZE + TFTP_BLOCKNO_SIZE + TFTP_MAX_PAYLOAD ) 40 | 41 | uint16_t lastPacket = 0; 42 | 43 | /* Opcode?: tftp operation is unsupported. The bootloader only supports 'put' */ 44 | #define TFTP_OPCODE_ERROR_LEN 12 45 | char tftp_opcode_error_packet[] PROGMEM = "\12" "\0\5" "\0\0" "Opcode?"; 46 | 47 | /* Full: Binary image file is larger than the available space. */ 48 | #define TFTP_FULL_ERROR_LEN 9 49 | char tftp_full_error_packet[] PROGMEM = "\x09" "\0\5" "\0\3" "Full"; 50 | 51 | /* General catch-all error for unknown errors */ 52 | #define TFTP_UNKNOWN_ERROR_LEN 10 53 | char tftp_unknown_error_packet[] PROGMEM = "\10" "\0\5" "\0\0" "Error"; 54 | 55 | /* Invalid image file: Doesn't look like a binary image file */ 56 | #define TFTP_INVALID_IMAGE 23 57 | char tftp_invalid_image_packet[] PROGMEM = "\23" "\0\5" "\0\0" "Invalid image file"; 58 | 59 | 60 | uint8_t processPacket(uint16_t packetSize) { 61 | uint8_t buffer[TFTP_PACKET_MAX_SIZE]; 62 | uint16_t readPointer; 63 | uint16_t writeAddr; 64 | 65 | // Transfer entire packet to RAM 66 | uint8_t* bufPtr = buffer; 67 | uint16_t count; 68 | 69 | //TRACE("Copying packet of length "); 70 | //tracenum(packetSize); 71 | //TRACE("\n"); 72 | 73 | readPointer = netReadWord(REG_S3_RX_RD0) + S3_RX_START; 74 | for (count=TFTP_PACKET_MAX_SIZE; count--;) { 75 | *bufPtr++ = netReadReg(readPointer++); 76 | if (readPointer == S3_RX_END) readPointer = S3_RX_START; 77 | } 78 | netWriteWord(REG_S3_RX_RD0,readPointer); // Write back new pointer 79 | 80 | // Dump packet 81 | bufPtr = buffer; 82 | for (count=TFTP_PACKET_MAX_SIZE; count--;) { 83 | uint16_t val = *bufPtr++; 84 | val |= (*bufPtr++) << 8; 85 | //tracenum(val); 86 | //TRACE(" "); 87 | } 88 | 89 | //TRACE("Setting return address\n"); 90 | 91 | // Set up return IP address and port 92 | uint8_t i; 93 | for (i=0; i<6; i++) netWriteReg(REG_S3_DIPR0+i,buffer[i]); 94 | 95 | // Parse packet 96 | uint16_t tftpDataLen = (buffer[6]<<8) + buffer[7]; 97 | uint16_t tftpOpcode = (buffer[8]<<8) + buffer[9]; 98 | uint16_t tftpBlock = (buffer[10]<<8) + buffer[11]; 99 | 100 | uint8_t returnCode = ERROR_UNKNOWN; 101 | uint16_t packetLength; 102 | switch (tftpOpcode) { 103 | case TFTP_OPCODE_RRQ: // Read request 104 | default: 105 | //tracenum(tftpOpcode); 106 | //TRACE("is invalid opcode\n"); 107 | // Invalid - return error 108 | returnCode = ERROR_INVALID; 109 | break; 110 | 111 | case TFTP_OPCODE_WRQ: // Write request 112 | //TRACE("Write request\n"); 113 | netWriteReg(REG_S3_CR,CR_RECV); 114 | netWriteReg(REG_S3_CR,CR_CLOSE); 115 | do { 116 | netWriteReg(REG_S3_MR,MR_UDP); 117 | netWriteReg(REG_S3_CR,CR_OPEN); 118 | netWriteWord(REG_S3_PORT0,(buffer[4]<<8) | ~buffer[5] ); // Generate a 'random' TID (RFC1350) 119 | if (netReadReg(REG_S3_SR) != SOCK_UDP) 120 | netWriteReg(REG_S3_CR,CR_CLOSE); 121 | } while (netReadReg(REG_S3_SR) != SOCK_UDP); 122 | //TRACE("Changed to port "); 123 | //tracenum((buffer[4]<<8) | (buffer[5]^0x55)); 124 | //TRACE("\n"); 125 | lastPacket = 0; 126 | returnCode = ACK; // Send back acknowledge for packet 0 127 | break; 128 | 129 | case TFTP_OPCODE_DATA: 130 | packetLength = tftpDataLen; 131 | lastPacket = tftpBlock; 132 | writeAddr = (tftpBlock-1) << 9; // Flash write address for this block 133 | //TRACE("Data for block "); 134 | //tracenum(lastPacket); 135 | //TRACE("\n"); 136 | 137 | 138 | if ((writeAddr+packetLength) > MAX_ADDR) { 139 | // Flash is full - abort with an error before a bootloader overwrite occurs 140 | // 141 | // Application is now corrupt, so do not hand over. 142 | // 143 | returnCode = ERROR_FULL; 144 | } else { 145 | //TRACE("Writing data from address "); 146 | //tracenum(writeAddr); 147 | //TRACE("\n"); 148 | 149 | uint8_t* pageBase = buffer + 12; // Start of block data 150 | uint16_t offset = 0; // Block offset 151 | 152 | // Round up packet length to a full flash sector size 153 | while (packetLength % SPM_PAGESIZE) packetLength++; 154 | 155 | if (writeAddr == 0) { 156 | // First sector - validate 157 | if (!validImage(pageBase)) { 158 | returnCode = INVALID_IMAGE; 159 | break; 160 | } 161 | } 162 | 163 | // Flash packets 164 | for (offset=0; offset < packetLength;) { 165 | uint16_t writeValue = (pageBase[offset]) | (pageBase[offset+1]<<8); 166 | boot_page_fill(writeAddr+offset,writeValue); 167 | offset+=2; 168 | if (offset % SPM_PAGESIZE == 0) { 169 | boot_page_erase(writeAddr + offset - SPM_PAGESIZE); 170 | boot_spm_busy_wait(); 171 | boot_page_write(writeAddr + offset - SPM_PAGESIZE); 172 | boot_spm_busy_wait(); 173 | boot_rww_enable(); 174 | } 175 | } 176 | 177 | if (packetLength < TFTP_DATA_SIZE) { 178 | // Flash is complete 179 | // Hand over to application 180 | returnCode = FINAL_ACK; 181 | } else { 182 | returnCode = ACK; 183 | } 184 | } 185 | break; 186 | 187 | case TFTP_OPCODE_ACK: // Acknowledgement 188 | //TRACE("Ack\n"); 189 | break; 190 | 191 | case TFTP_OPCODE_ERROR: // Error signal 192 | //TRACE("Error\n"); 193 | break; 194 | 195 | } 196 | return returnCode; 197 | } 198 | 199 | void sendResponse(uint16_t response) { 200 | uint8_t txBuffer[100]; 201 | uint8_t *txPtr = txBuffer; 202 | uint8_t packetLength; 203 | uint16_t writePointer; 204 | writePointer = netReadWord(REG_S3_TX_WR0) + S3_TX_START; 205 | switch (response) { 206 | default: 207 | case ERROR_UNKNOWN: 208 | // Send unknown error packet 209 | packetLength = TFTP_UNKNOWN_ERROR_LEN; 210 | memcpy_P(txBuffer,tftp_unknown_error_packet,packetLength); 211 | break; 212 | 213 | case ERROR_INVALID: 214 | // Send invalid opcode packet 215 | packetLength = TFTP_OPCODE_ERROR_LEN; 216 | memcpy_P(txBuffer,tftp_opcode_error_packet,packetLength); 217 | break; 218 | 219 | case ERROR_FULL: 220 | // Send unknown error packet 221 | packetLength = TFTP_FULL_ERROR_LEN; 222 | memcpy_P(txBuffer,tftp_full_error_packet,packetLength); 223 | break; 224 | 225 | case ACK: 226 | case FINAL_ACK: 227 | //TRACE("Send ACK "); 228 | //tracenum(lastPacket); 229 | //TRACE("\n"); 230 | packetLength = 4; 231 | *txPtr++ = TFTP_OPCODE_ACK >> 8; 232 | *txPtr++ = TFTP_OPCODE_ACK & 0xff; 233 | *txPtr++ = lastPacket >> 8; 234 | *txPtr = lastPacket & 0xff; 235 | break; 236 | } 237 | txPtr = txBuffer; 238 | while (packetLength--) { 239 | netWriteReg(writePointer++, *txPtr++); 240 | if (writePointer == S3_TX_END) writePointer = S3_TX_START; 241 | } 242 | netWriteWord(REG_S3_TX_WR0, writePointer - S3_TX_START); 243 | netWriteReg(REG_S3_CR,CR_SEND); 244 | while (netReadReg(REG_S3_CR)); 245 | } 246 | 247 | 248 | void tftpInit() { 249 | // Open socket 250 | do { 251 | netWriteWord(REG_S3_PORT0,TFTP_PORT); 252 | netWriteReg(REG_S3_MR,MR_UDP); 253 | netWriteReg(REG_S3_CR,CR_OPEN); 254 | if (netReadReg(REG_S3_SR) != SOCK_UDP) 255 | netWriteReg(REG_S3_CR,CR_CLOSE); 256 | } while (netReadReg(REG_S3_SR) != SOCK_UDP); 257 | } 258 | 259 | uint8_t tftpPoll() { 260 | uint8_t response = ACK; 261 | uint16_t packetSize = netReadWord(REG_S3_RX_RSR0); 262 | if (packetSize) { 263 | response = processPacket(packetSize); 264 | sendResponse(response); 265 | } 266 | if ((response == FINAL_ACK) || timedOut()) { 267 | netWriteReg(REG_S3_CR,CR_CLOSE); 268 | return 0; // Complete 269 | } 270 | return 1; // tftp continues 271 | } 272 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/tftp.h: -------------------------------------------------------------------------------- 1 | // TFTP Opcode values from RFC 1350 2 | // 3 | #define TFTP_OPCODE_RRQ 1 4 | #define TFTP_OPCODE_WRQ 2 5 | #define TFTP_OPCODE_DATA 3 6 | #define TFTP_OPCODE_ACK 4 7 | #define TFTP_OPCODE_ERROR 5 8 | 9 | // TFTP Error codes from RFC 1350 10 | // 11 | #define TFTP_ERROR_UNDEF 0 12 | #define TFTP_ERROR_NOT_FOUND 1 13 | #define TFTP_ERROR_ACCESS 2 14 | #define TFTP_ERROR_FULL 3 15 | #define TFTP_ERROR_ILLEGAL_OP 4 16 | #define TFTP_ERROR_UNKNOWN_XFER 4 17 | #define TFTP_ERROR_EXISTS 6 18 | #define TFTP_ERROR_NO_SUCH_USER 7 19 | 20 | 21 | #define TFTP_PORT 69 22 | 23 | void tftpInit(); 24 | uint8_t tftpPoll(); 25 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/validate.c: -------------------------------------------------------------------------------- 1 | /* Validate first sector is a genuine image */ 2 | #include 3 | 4 | uint8_t validImage(uint8_t *base) { 5 | /* Check that a jump table is present in the first flash sector */ 6 | uint8_t i; 7 | for (i=0; i<0x34; i+=4) { 8 | // For each vector, check it is of the form: 9 | // 0x0C 0x94 0xWX 0xYZ ; JMP 0xWXYZ 10 | // 11 | if (base[i] != 0x0C) return 0; 12 | if (base[i+1] != 0x94) return 0; 13 | } 14 | return 1; 15 | } 16 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/validate.h: -------------------------------------------------------------------------------- 1 | uint8_t validImage(uint8_t *base); 2 | -------------------------------------------------------------------------------- /eth-bootloader/firmware/w5100_reg.h: -------------------------------------------------------------------------------- 1 | #define REG_MR 0x000 2 | #define REG_GAR0 0x001 3 | #define REG_GAR1 0x002 4 | #define REG_GAR2 0x003 5 | #define REG_GAR3 0x004 6 | #define REG_SUBR0 0x005 7 | #define REG_SUBR1 0x006 8 | #define REG_SUBR2 0x007 9 | #define REG_SUBR3 0x008 10 | #define REG_SHAR0 0x009 11 | #define REG_SHAR1 0x00A 12 | #define REG_SHAR2 0x00B 13 | #define REG_SHAR3 0x00C 14 | #define REG_SHAR4 0x00D 15 | #define REG_SHAR5 0x00E 16 | #define REG_SIPR0 0x00F 17 | #define REG_SIPR1 0x010 18 | #define REG_SIPR2 0x011 19 | #define REG_SIPR3 0x012 20 | #define REG_IR 0x015 21 | #define REG_IMR 0x016 22 | #define REG_RTR0 0x017 23 | #define REG_RTR1 0x018 24 | #define REG_RCR 0x019 25 | #define REG_RMSR 0x01A 26 | #define REG_TMSR 0x01B 27 | #define REG_PATR0 0x01C 28 | #define REG_PATR1 0x01D 29 | #define REG_PTIMER 0x028 30 | #define REG_PMAGIC 0x029 31 | #define REG_UIPR0 0x02A 32 | #define REG_UIPR1 0x02B 33 | #define REG_UIPR2 0x02C 34 | #define REG_UIPR3 0x02D 35 | #define REG_UPORT0 0x02E 36 | #define REG_UPORT1 0x02F 37 | 38 | #define REG_S0_MR 0x400 39 | #define REG_S0_CR 0x401 40 | #define REG_S0_IR 0x402 41 | #define REG_S0_SR 0x403 42 | #define REG_S0_PORT0 0x404 43 | #define REG_S0_PORT1 0x405 44 | #define REG_S0_DHAR0 0x406 45 | #define REG_S0_DHAR1 0x407 46 | #define REG_S0_DHAR2 0x408 47 | #define REG_S0_DHAR3 0x409 48 | #define REG_S0_DHAR4 0x40A 49 | #define REG_S0_DHAR5 0x40B 50 | #define REG_S0_DIPR0 0x40C 51 | #define REG_S0_DIPR1 0x40D 52 | #define REG_S0_DIPR2 0x40E 53 | #define REG_S0_DIPR3 0x40F 54 | #define REG_S0_DPORT0 0x410 55 | #define REG_S0_DPORT1 0x411 56 | #define REG_S0_MSSR0 0x412 57 | #define REG_S0_MSSR1 0x413 58 | #define REG_S0_PROTO 0x414 59 | #define REG_S0_TOS 0x415 60 | #define REG_S0_TTL 0x416 61 | #define REG_S0_TX_FSR0 0x420 62 | #define REG_S0_TX_FSR1 0x421 63 | #define REG_S0_TX_RD0 0x422 64 | #define REG_S0_TX_RD1 0x423 65 | #define REG_S0_TX_WR0 0x424 66 | #define REG_S0_TX_WR1 0x425 67 | #define REG_S0_RX_RSR0 0x426 68 | #define REG_S0_RX_RSR1 0x427 69 | #define REG_S0_RX_RD0 0x428 70 | #define REG_S0_RX_RD1 0x429 71 | 72 | #define REG_S1_MR 0x500 73 | #define REG_S1_CR 0x501 74 | #define REG_S1_IR 0x502 75 | #define REG_S1_SR 0x503 76 | #define REG_S1_PORT0 0x504 77 | #define REG_S1_PORT1 0x505 78 | #define REG_S1_DHAR0 0x506 79 | #define REG_S1_DHAR1 0x507 80 | #define REG_S1_DHAR2 0x508 81 | #define REG_S1_DHAR3 0x509 82 | #define REG_S1_DHAR4 0x50A 83 | #define REG_S1_DHAR5 0x50B 84 | #define REG_S1_DIPR0 0x50C 85 | #define REG_S1_DIPR1 0x50D 86 | #define REG_S1_DIPR2 0x50E 87 | #define REG_S1_DIPR3 0x50F 88 | #define REG_S1_DPORT0 0x510 89 | #define REG_S1_DPORT1 0x511 90 | #define REG_S1_MSSR0 0x512 91 | #define REG_S1_MSSR1 0x513 92 | #define REG_S1_PROTO 0x514 93 | #define REG_S1_TOS 0x515 94 | #define REG_S1_TTL 0x516 95 | #define REG_S1_TX_FSR0 0x520 96 | #define REG_S1_TX_FSR1 0x521 97 | #define REG_S1_TX_RD0 0x522 98 | #define REG_S1_TX_RD1 0x523 99 | #define REG_S1_TX_WR0 0x524 100 | #define REG_S1_TX_WR1 0x525 101 | #define REG_S1_RX_RSR0 0x526 102 | #define REG_S1_RX_RSR1 0x527 103 | #define REG_S1_RX_RD0 0x528 104 | #define REG_S1_RX_RD1 0x529 105 | 106 | #define REG_S2_MR 0x600 107 | #define REG_S2_CR 0x601 108 | #define REG_S2_IR 0x602 109 | #define REG_S2_SR 0x603 110 | #define REG_S2_PORT0 0x604 111 | #define REG_S2_PORT1 0x605 112 | #define REG_S2_DHAR0 0x606 113 | #define REG_S2_DHAR1 0x607 114 | #define REG_S2_DHAR2 0x608 115 | #define REG_S2_DHAR3 0x609 116 | #define REG_S2_DHAR4 0x60A 117 | #define REG_S2_DHAR5 0x60B 118 | #define REG_S2_DIPR0 0x60C 119 | #define REG_S2_DIPR1 0x60D 120 | #define REG_S2_DIPR2 0x60E 121 | #define REG_S2_DIPR3 0x60F 122 | #define REG_S2_DPORT0 0x610 123 | #define REG_S2_DPORT1 0x611 124 | #define REG_S2_MSSR0 0x612 125 | #define REG_S2_MSSR1 0x613 126 | #define REG_S2_PROTO 0x614 127 | #define REG_S2_TOS 0x615 128 | #define REG_S2_TTL 0x616 129 | #define REG_S2_TX_FSR0 0x620 130 | #define REG_S2_TX_FSR1 0x621 131 | #define REG_S2_TX_RD0 0x622 132 | #define REG_S2_TX_RD1 0x623 133 | #define REG_S2_TX_WR0 0x624 134 | #define REG_S2_TX_WR1 0x625 135 | #define REG_S2_RX_RSR0 0x626 136 | #define REG_S2_RX_RSR1 0x627 137 | #define REG_S2_RX_RD0 0x628 138 | #define REG_S2_RX_RD1 0x629 139 | 140 | #define REG_S3_MR 0x700 141 | #define REG_S3_CR 0x701 142 | #define REG_S3_IR 0x702 143 | #define REG_S3_SR 0x703 144 | #define REG_S3_PORT0 0x704 145 | #define REG_S3_PORT1 0x705 146 | #define REG_S3_DHAR0 0x706 147 | #define REG_S3_DHAR1 0x707 148 | #define REG_S3_DHAR2 0x708 149 | #define REG_S3_DHAR3 0x709 150 | #define REG_S3_DHAR4 0x70A 151 | #define REG_S3_DHAR5 0x70B 152 | #define REG_S3_DIPR0 0x70C 153 | #define REG_S3_DIPR1 0x70D 154 | #define REG_S3_DIPR2 0x70E 155 | #define REG_S3_DIPR3 0x70F 156 | #define REG_S3_DPORT0 0x710 157 | #define REG_S3_DPORT1 0x711 158 | #define REG_S3_MSSR0 0x712 159 | #define REG_S3_MSSR1 0x713 160 | #define REG_S3_PROTO 0x714 161 | #define REG_S3_TOS 0x715 162 | #define REG_S3_TTL 0x716 163 | #define REG_S3_TX_FSR0 0x720 164 | #define REG_S3_TX_FSR1 0x721 165 | #define REG_S3_TX_RD0 0x722 166 | #define REG_S3_TX_RD1 0x723 167 | #define REG_S3_TX_WR0 0x724 168 | #define REG_S3_TX_WR1 0x725 169 | #define REG_S3_RX_RSR0 0x726 170 | #define REG_S3_RX_RSR1 0x727 171 | #define REG_S3_RX_RD0 0x728 172 | #define REG_S3_RX_RD1 0x729 173 | 174 | #define S0_TX_START 0x4000 175 | #define S0_TX_END 0x4800 176 | #define S1_TX_START 0x4800 177 | #define S1_TX_END 0x5000 178 | #define S2_TX_START 0x5000 179 | #define S2_TX_END 0x5800 180 | #define S3_TX_START 0x5800 181 | #define S3_TX_END 0x6000 182 | #define S0_RX_START 0x6000 183 | #define S0_RX_END 0x6800 184 | #define S1_RX_START 0x6800 185 | #define S1_RX_END 0x7000 186 | #define S2_RX_START 0x7000 187 | #define S2_RX_END 0x7800 188 | #define S3_RX_START 0x7800 189 | #define S3_RX_END 0x8000 190 | 191 | 192 | #define MR_CLOSED 0x00 193 | #define MR_TCP 0x01 194 | #define MR_UDP 0x02 195 | #define MR_IPRAW 0x03 196 | #define MR_MACRAW 0x04 197 | #define MR_PPPOE 0x05 198 | 199 | #define CR_OPEN 0x01 200 | #define CR_LISTEN 0x02 201 | #define CR_CONNECT 0x04 202 | #define CR_DISCON 0x08 203 | #define CR_CLOSE 0x10 204 | #define CR_SEND 0x20 205 | #define CR_SEND_MAC 0x21 206 | #define CR_SEND_KEEP 0x22 207 | #define CR_RECV 0x40 208 | 209 | #define SOCK_CLOSED 0x00 210 | #define SOCK_ARP1 0x11 211 | #define SOCK_INIT 0x13 212 | #define SOCK_LISTEN 0x14 213 | #define SOCK_SYNSENT 0x15 214 | #define SOCK_SYNRECV 0x16 215 | #define SOCK_ESTABLISHED 0x17 216 | #define SOCK_FIN_WAIT 0x18 217 | #define SOCK_CLOSING 0x1A 218 | #define SOCK_TIME_WAIT 0x1B 219 | #define SOCK_CLOSE_WAIT 0x1C 220 | #define SOCK_LAST_ACK 0x1D 221 | #define SOCK_ARP2 0x21 222 | #define SOCK_UDP 0x22 223 | #define SOCK_ARP3 0x31 224 | #define SOCK_IPRAW 0x32 225 | #define SOCK_MACRAW 0x42 226 | #define SOCK_PPPOE 0x5F 227 | --------------------------------------------------------------------------------