diff --git a/avr/devices/0BUILD b/avr/devices/0BUILD
index 94f5ce1..99d2668 100644
--- a/avr/devices/0BUILD
+++ b/avr/devices/0BUILD
@@ -41,6 +41,7 @@
r05
r06
t03
+ s03
diff --git a/avr/devices/s03/.gitignore b/avr/devices/s03/.gitignore
new file mode 100644
index 0000000..8e0618c
--- /dev/null
+++ b/avr/devices/s03/.gitignore
@@ -0,0 +1,2 @@
+*.eep.hex
+*.obj
diff --git a/avr/devices/s03/0BUILD b/avr/devices/s03/0BUILD
new file mode 100644
index 0000000..0829603
--- /dev/null
+++ b/avr/devices/s03/0BUILD
@@ -0,0 +1,22 @@
+
+
+
+
+
+ boot
+ main
+
+
+
+ aqua_s03.xml
+
+
+
+ defs.asm
+ README
+
+
+
+
+
+
diff --git a/avr/devices/s03/README b/avr/devices/s03/README
new file mode 100644
index 0000000..b6eff6d
--- /dev/null
+++ b/avr/devices/s03/README
@@ -0,0 +1,9 @@
+
+S03
+===
+
+- Role: Router
+- MCU: AtMega 644P
+- Connection: RJ45
+- Periphery:
+
diff --git a/avr/devices/s03/aqua_s03.xml b/avr/devices/s03/aqua_s03.xml
new file mode 100644
index 0000000..6e9685a
--- /dev/null
+++ b/avr/devices/s03/aqua_s03.xml
@@ -0,0 +1,12 @@
+
+
+ AQUA
+ S
+ 3
+
+
+
+
+
+
+
diff --git a/avr/devices/s03/boot/0BUILD b/avr/devices/s03/boot/0BUILD
new file mode 100644
index 0000000..2dae797
--- /dev/null
+++ b/avr/devices/s03/boot/0BUILD
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+ -I $(builddir)
+ -I $(srcdir)
+ -I $(topsrcdir)/avr
+ -I $(topbuilddir)/avr
+
+
+
+
+ boot.asm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/avr/devices/s03/boot/boot.asm b/avr/devices/s03/boot/boot.asm
new file mode 100644
index 0000000..18e3064
--- /dev/null
+++ b/avr/devices/s03/boot/boot.asm
@@ -0,0 +1,159 @@
+; ***************************************************************************
+; Source file for base system node on AtMega 644P
+;
+; This is for the maintenance system (i.e. the flash loader).
+;
+; All definitions and changes should go into this file.
+; ***************************************************************************
+
+.equ clock=20000000 ; Define the clock frequency
+
+.nolist
+.include "include/m644Pdef.inc" ; Define device ATmega644P
+.list
+
+.include "../defs.asm"
+.include "devices/all/defs.asm"
+
+.include "common/calls.asm"
+.include "common/utils_wait.asm"
+.include "common/utils_io.asm"
+
+
+
+; ***************************************************************************
+; defines
+
+; ---------------------------------------------------------------------------
+; generic
+
+
+.equ NET_BUFFERS_NUM = 6
+.equ NET_BUFFERS_SIZE = 32
+
+
+
+; ---------------------------------------------------------------------------
+; firmware settings
+
+.equ FIRMWARE_VERSION_MAJOR = 0
+.equ FIRMWARE_VERSION_MINOR = 0
+.equ FIRMWARE_VERSION_PATCHLEVEL = 1
+
+
+
+; ---------------------------------------------------------------------------
+; LED
+
+.equ LED_DDR = DDRB
+.equ LED_PORT = PORTB
+.equ LED_PIN = PINB
+.equ LED_PINNUM = PORTB0
+
+
+
+
+
+; ***************************************************************************
+; code segment
+
+.cseg
+.org 0x0000
+
+
+
+; ---------------------------------------------------------------------------
+; Reset and interrupt vectors
+ jmp main ; 1: Reset vector RESET
+ jmp irqNotSet ; 2: INT0 External Interrupt Request 0
+ jmp irqNotSet ; 3: INT1 External Interrupt Request 1
+ jmp irqNotSet ; 4: INT2 External Interrupt Request 2
+ jmp irqNotSet ; 5: PCINT0 Pin Change Interrupt Request 0
+ jmp irqNotSet ; 6: PCINT1 Pin Change Interrupt Request 1
+ jmp irqNotSet ; 7: PCINT2 Pin Change Interrupt Request 2
+ jmp irqNotSet ; 8: PCINT3 Pin Change Interrupt Request 3
+ jmp irqNotSet ; 9: WDT Watchdog Time-out Interrupt
+ jmp irqNotSet ; 10: TIMER2_COMPA Timer/Counter2 Compare Match A
+ jmp irqNotSet ; 11: TIMER2_COMPB Timer/Counter2 Compare Match B
+ jmp irqNotSet ; 12: TIMER2_OVF Timer/Counter2 Overflow
+ jmp irqNotSet ; 13: TIMER1_CAPT Timer/Counter1 Capture Event
+ jmp irqNotSet ; 14: TIMER1_COMPA Timer/Counter1 Compare Match A
+ jmp irqNotSet ; 15: TIMER1_COMPB Timer/Counter1 Compare Match B
+ jmp irqNotSet ; 16: TIMER1_OVF Timer/Counter1 Overflow
+ jmp irqNotSet ; 17: TIMER0_COMPA Timer/Counter0 Compare Match A
+ jmp irqNotSet ; 18: TIMER0_COMPB Timer/Counter0 Compare Match B
+ jmp irqNotSet ; 19: TIMER0_OVF Timer/Counter0 Overflow
+ jmp irqNotSet ; 20: SPI_STC Serial Transfer Complete
+ jmp irqNotSet ; 21: USART0_RXC USART0 Rx Complete
+ jmp irqNotSet ; 22: USART0_UDRE USART0 Data Register Empty
+ jmp irqNotSet ; 23: USART0_TXC USART0 Tx Complete
+ jmp irqNotSet ; 24: ANA_COMP Analog Comparator
+ jmp irqNotSet ; 25: ADC ADC Conversion Complete
+ jmp irqNotSet ; 26: EE_RDY EEPROM Ready
+ jmp irqNotSet ; 27: TWI 2-Wire Interface
+ jmp irqNotSet ; 28: SPM_RDY Store Program Memory Ready
+
+
+
+; ---------------------------------------------------------------------------
+; Device Info Block
+
+devInfoBlock: ; 12 bytes
+devInfoManufacturer: .db 'A', 'Q', 'U', 'A'
+devInfoId: .db DEVICEINFO_ID, 0
+devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision
+firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR
+ .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL
+
+firmwareStart:
+ jmp main ; will be overwritten when flashing
+
+irqNotSet:
+ reti
+
+
+
+; ***************************************************************************
+; main code
+
+
+.org BOOTLOADER_ADDR
+
+
+main:
+; ldi r16, 0xb0 ; orig: a0
+; out OSCCAL, r16
+ jmp bootLoader ; this routine is in modules/bootloader/main.asm
+
+
+
+; ***************************************************************************
+; includes
+
+.include "common/wait_10us.asm"
+.include "common/utils_copy_from_flash.asm"
+.include "common/utils_copy_sdram.asm"
+
+.include "modules/flash/defs.asm"
+.include "modules/flash/eeprom.asm"
+.include "modules/flash/io.asm"
+.include "modules/flash/io_com2w.asm"
+.include "modules/flash/flash1pmega.asm"
+.include "modules/flash/flashxp.asm"
+.include "modules/flash/flashprocess.asm"
+.include "modules/flash/wait.asm"
+.include "modules/bootloader/main.asm"
+.include "modules/network/msg/defs.asm"
+.include "modules/network/msg/crc.asm"
+
+;.include "common/debug.asm"
+
+
+
+systemSetSpeed:
+ ; speed not changeable at runtime on this device
+ ret
+
+
+
+
diff --git a/avr/devices/s03/defs.asm b/avr/devices/s03/defs.asm
new file mode 100644
index 0000000..b284a31
--- /dev/null
+++ b/avr/devices/s03/defs.asm
@@ -0,0 +1,127 @@
+; ***************************************************************************
+; copyright : (C) 2025 by Martin Preuss
+; email : martin@libchipcard.de
+;
+; ***************************************************************************
+; * This file is part of the project "AqHome". *
+; * Please see toplevel file COPYING of that project for license details. *
+; ***************************************************************************
+
+
+; ***************************************************************************
+;
+; AtMega644
+; --------
+; LED PB0 1 40 PA0 COM0-CLK
+; PB1 2 39 PA1 COM1-CLK
+; PB2 3 38 PA2 COM2-CLK
+; PB3 4 37 PA3 COM3-CLK
+; PB4 5 36 PA4 COM4-CLK
+; MOSI PB5 6 35 PA5 COM5-CLK
+; MISO PB6 7 34 PA6 COM6-CLK
+; SCK PB7 8 33 PA7 COM7-CLK
+; /RESET 9 32 AREF
+; VCC 10 31 GND
+; GND 11 30 AVCC
+; XTAL2 12 29 PC7 COM7-DATA
+; XTAL1 13 28 PC6 COM6-DATA
+; COM0-LED PD0 14 27 PC5 COM5-DATA
+; COM1-LED PD1 15 26 PC4 COM4-DATA
+; COM2-LED PD2 16 25 PC3 COM3-DATA
+; COM3-LED PD3 17 24 PC2 COM2-DATA
+; COM4-LED PD4 18 23 PC1 COM1-DATA
+; COM5-LED PD5 19 22 PC0 COM0-DATA
+; COM6-LED PD6 20 21 COM7-LED
+; --------
+;
+; ***************************************************************************
+
+
+
+.equ BOOTLOADER_ADDR = 0x7c00
+
+.equ FIRMWARE_VARIANT_BOOT = 0
+.equ FIRMWARE_VARIANT_TEMP_WINDOW = 1
+
+.equ DEVICEINFO_ID = 'S'
+.equ DEVICEINFO_VERSION = 3
+.equ DEVICEINFO_REVISION = 0
+
+
+
+; ---------------------------------------------------------------------------
+; LED module
+
+.equ LED_SIMPLE_ONTIME = 1 ; shorter
+.equ LED_SIMPLE_OFFTIME = 50 ; longer
+.equ LED_SIMPLE_DDR = DDRB
+.equ LED_SIMPLE_PORT = PORTB
+.equ LED_SIMPLE_PORTIN = PINB
+.equ LED_SIMPLE_PINNUM = PORTB0
+
+
+
+; ---------------------------------------------------------------------------
+; COM module
+
+.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
+.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
+
+.equ COM_DATA_DDR = DDRC
+.equ COM_DATA_INPUT = PINC
+.equ COM_DATA_OUTPUT = PORTC
+.equ COM_DATA_PIN = PORTC6
+
+.equ COM_CLK_DDR = DDRA
+.equ COM_CLK_INPUT = PINA
+.equ COM_CLK_OUTPUT = PORTA
+.equ COM_CLK_PIN = PORTA6
+
+.equ COM_IRQ_ADDR_M_CLK = PCICR
+.equ COM_IRQ_BIT_M_CLK = PCIE0
+
+.equ COM_IRQ_ADDR_F_CLK = PCIFR
+.equ COM_IRQ_BIT_F_CLK = PCIF0
+
+.equ COM_IRQ_ADDR_CLK = PCMSK0
+
+
+
+.equ COM_PORTS = 8
+
+.equ COM_MASK_CLK0 = (1<
+
+
+
+
+
+
+ -I $(builddir)
+ -I $(srcdir)
+ -I $(topsrcdir)/avr
+ -I $(topbuilddir)/avr
+
+
+
+
+ main.asm
+
+
+
+
+
+
+
+
+
+
+
+ data.asm
+
+
+
+
+
+
diff --git a/avr/devices/s03/main/data.asm b/avr/devices/s03/main/data.asm
new file mode 100644
index 0000000..31ccc2f
--- /dev/null
+++ b/avr/devices/s03/main/data.asm
@@ -0,0 +1,14 @@
+; ***************************************************************************
+; copyright : (C) 2025 by Martin Preuss
+; email : martin@libchipcard.de
+;
+; ***************************************************************************
+; * This file is part of the project "AqHome". *
+; * Please see toplevel file COPYING of that project for license details. *
+; ***************************************************************************
+
+
+
+.dseg
+
+
diff --git a/avr/devices/s03/main/main.asm b/avr/devices/s03/main/main.asm
new file mode 100644
index 0000000..c8773f1
--- /dev/null
+++ b/avr/devices/s03/main/main.asm
@@ -0,0 +1,244 @@
+; ***************************************************************************
+; copyright : (C) 2025 by Martin Preuss
+; email : martin@libchipcard.de
+;
+; ***************************************************************************
+; * This file is part of the project "AqHome". *
+; * Please see toplevel file COPYING of that project for license details. *
+; ***************************************************************************
+
+;.equ clock=1000000 ; Define the clock frequency
+.equ clock=20000000 ; Define the clock frequency
+
+
+
+.nolist
+.include "include/m644Pdef.inc" ; Define device ATmega644P
+.list
+
+.include "version.asm"
+.include "../defs.asm"
+.include "./data.asm"
+
+.include "devices/all/defs.asm"
+.include "common/calls.asm"
+.include "common/utils_wait.asm"
+.include "common/utils_io.asm"
+
+
+
+; ***************************************************************************
+; defines
+
+; ---------------------------------------------------------------------------
+; generic
+
+.equ NET_BUFFERS_NUM = 96
+.equ NET_MSGNUMINBUF_SIZE = 64 ; max buffer nums in ringbuffer (global incoming)
+.equ NET_IFACE_OUTMSGBUF_SIZE = 16 ; max buffer nums in ringbuffer (per interface outbound)
+.equ COM2WN_IO_RINGBUFFER_SIZE = 128
+
+
+
+; ---------------------------------------------------------------------------
+; firmware settings including list of modules used
+
+#define MAIN_WITHOUT_MSG_HANDLING ; message handling done here
+
+; #define MODULES_TIMER
+#define MODULES_CLOCK
+;#define MODULES_XRAM
+;#define MODULES_HEAP
+#define MODULES_LED_SIMPLE
+#define MODULES_NETWORK
+#define MODULES_COM2WN
+;#define MODULES_COMONUART0
+;#define MODULES_UART_HW
+;#define MODULES_UART_BITBANG
+;#define MODULES_SPI_HW
+;#define MODULES_ILI9341
+;#define MODULES_FONT
+;#define MODULES_WIN
+;#define MODULES_TWI_MASTER
+;#define MODULES_LCD
+;#define LCD_MINIMAL_FONT
+;#define MODULES_SI7021
+;#define MODULES_SGP30
+;#define MODULES_SGP40
+;#define MODULES_STATS
+;#define MODULES_OWI_MASTER
+;#define MODULES_DS18B20
+;#define MODULES_MOTION
+;#define MODULES_CCS811
+
+;#define APPS_NETWORK
+;#define APPS_MOTION
+;#define APPS_REPORTSENSORS
+;#define APPS_STATS
+#define APPS_HUB
+
+
+
+; ---------------------------------------------------------------------------
+; defines for values
+
+.equ VALUE_ID_HUB_SETRANGE1 = 0x11
+.equ VALUE_ID_HUB_SETRANGE2 = 0x12
+.equ VALUE_ID_HUB_SETRANGE3 = 0x13
+.equ VALUE_ID_HUB_SETRANGE4 = 0x14
+.equ VALUE_ID_HUB_SETRANGE5 = 0x15
+.equ VALUE_ID_HUB_SETRANGE6 = 0x16
+.equ VALUE_ID_HUB_SETRANGE7 = 0x17
+.equ VALUE_ID_HUB_SETRANGE8 = 0x18
+
+.equ VALUE_ID_DEBUG = 0x7f
+
+.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88
+
+
+
+
+
+; ***************************************************************************
+; code segment
+
+.cseg
+.org 000000
+
+
+
+; ---------------------------------------------------------------------------
+; Reset and interrupt vectors
+ jmp BOOTLOADER_ADDR ; 1: Reset vector RESET
+ jmp irqNotSet ; 2: INT0 External Interrupt Request 0
+ jmp irqNotSet ; 3: INT1 External Interrupt Request 1
+ jmp irqNotSet ; 4: INT2 External Interrupt Request 2
+ jmp COM2WN_ClkChangeIsr ; 5: PCINT0 Pin Change Interrupt Request 0
+ jmp irqNotSet ; 6: PCINT1 Pin Change Interrupt Request 1
+ jmp irqNotSet ; 7: PCINT2 Pin Change Interrupt Request 2
+ jmp irqNotSet ; 8: PCINT3 Pin Change Interrupt Request 3
+ jmp irqNotSet ; 9: WDT Watchdog Time-out Interrupt
+ jmp irqNotSet ; 10: TIMER2_COMPA Timer/Counter2 Compare Match A
+ jmp irqNotSet ; 11: TIMER2_COMPB Timer/Counter2 Compare Match B
+ jmp irqNotSet ; 12: TIMER2_OVF Timer/Counter2 Overflow
+ jmp irqNotSet ; 13: TIMER1_CAPT Timer/Counter1 Capture Event
+ jmp irqNotSet ; 14: TIMER1_COMPA Timer/Counter1 Compare Match A
+ jmp irqNotSet ; 15: TIMER1_COMPB Timer/Counter1 Compare Match B
+ jmp irqNotSet ; 16: TIMER1_OVF Timer/Counter1 Overflow
+ jmp baseTimerIrqOC0A ; 17: TIMER0_COMPA Timer/Counter0 Compare Match A
+ jmp irqNotSet ; 18: TIMER0_COMPB Timer/Counter0 Compare Match B
+ jmp irqNotSet ; 19: TIMER0_OVF Timer/Counter0 Overflow
+ jmp irqNotSet ; 20: SPI_STC Serial Transfer Complete
+ jmp irqNotSet ; 21: USART0_RXC USART0 Rx Complete
+ jmp irqNotSet ; 22: USART0_UDRE USART0 Data Register Empty
+ jmp irqNotSet ; 23: USART0_TXC USART0 Tx Complete
+ jmp irqNotSet ; 24: ANA_COMP Analog Comparator
+ jmp irqNotSet ; 25: ADC ADC Conversion Complete
+ jmp irqNotSet ; 26: EE_RDY EEPROM Ready
+ jmp irqNotSet ; 27: TWI 2-Wire Interface
+ jmp irqNotSet ; 28: SPM_RDY Store Program Memory Ready
+
+
+
+devInfoBlock: ; 12 bytes
+devInfoManufacturer: .db 'A', 'Q', 'U', 'A'
+devInfoId: .db DEVICEINFO_ID, 0
+devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision
+firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR
+ .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL
+
+
+
+; ---------------------------------------------------------------------------
+; @routine firmwareStart @global
+
+firmwareStart:
+ rjmp main
+; @end
+
+
+irqNotSet:
+ reti
+
+
+
+; ---------------------------------------------------------------------------
+; @routine onSystemStart
+
+onSystemStart:
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine onMessageReceived
+;
+; Called on every message received
+
+onMessageReceived:
+ clc
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine onEvery100ms
+;
+; Called every 100ms. Add your routine calls here. No arguments, no results.
+
+onEvery100ms:
+onEverySecond:
+onEveryMinute:
+onEveryHour:
+onEveryDay:
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine onEveryLoop
+;
+; Called on every loop (i.e. after awakening from sleep).
+;
+onEveryLoop:
+ ret
+; @end
+
+
+
+
+
+; ***************************************************************************
+; includes
+
+.include "devices/all/hw_m644p.asm"
+.include "devices/all/includes.asm"
+
+;.include "common/debug.asm"
+
+;.include "modules/lcd2/font/font2.asm"
+;.include "modules/lcd2/font/font3.asm"
+;.include "modules/lcd2/font/font16x26.asm"
+;.include "modules/lcd2/font/font4.asm"
+;.include "modules/lcd2/font/font12x16.asm"
+;.include "modules/lcd2/font/font5.asm"
+;.include "modules/lcd2/font/font12x20.asm"
+;.include "common/list_t.asm"
+;.include "common/tree_t.asm"
+;.include "common/divide.asm"
+
+
+; ---------------------------------------------------------------------------
+; defines for network interface
+
+;.equ netInterfaceData = netUartIface
+;.equ netInterfaceData = uart_bitbang_iface
+.equ netInterfaceData = com2w0_iface
+
+
+
+
+
diff --git a/flashnode.sh b/flashnode.sh
index ba15e05..6370233 100755
--- a/flashnode.sh
+++ b/flashnode.sh
@@ -107,6 +107,13 @@ case $NODE in
EFUSE_ARG="-U efuse:w:0xFE:m"
FILE_ARG="-U flash:w:./0-build/avr/devices/r05/boot/r05_boot.hex"
;;
+ s03)
+ DEVICE_ARG="-p m644p"
+ HFUSE_ARG="-U hfuse:w:0x95:m"
+ LFUSE_ARG="-U lfuse:w:0xdF:m"
+ EFUSE_ARG="-U efuse:w:0xFF:m"
+ FILE_ARG="-U flash:w:./0-build/avr/devices/s03/boot/s03_boot.hex"
+ ;;
t03)
DEVICE_ARG="-p t841"
HFUSE_ARG="-U hfuse:w:0xD7:m"