diff --git a/avr/devices/all/modules_include.asm b/avr/devices/all/modules_include.asm
index e942160..a0af299 100644
--- a/avr/devices/all/modules_include.asm
+++ b/avr/devices/all/modules_include.asm
@@ -198,6 +198,19 @@ MODULE_END_COM2W:
.include "modules/spi_hw/main.asm"
#endif
+
+#ifdef MODULES_SPI_SW
+.include "modules/spi_sw/main.asm"
+#endif
+
+#ifdef MODULES_RAM_23LC512
+.include "modules/ram/23LC512/main.asm"
+#endif
+
+#ifdef MODULES_EE_25LC256
+.include "modules/eeprom/25LC256/main.asm"
+#endif
+
#ifdef MODULES_DS18B20
.include "modules/ds18b20/main2.asm"
#ifdef MODULES_NETWORK
diff --git a/avr/devices/all/modules_init.asm b/avr/devices/all/modules_init.asm
index 916493f..1f5c2de 100644
--- a/avr/devices/all/modules_init.asm
+++ b/avr/devices/all/modules_init.asm
@@ -133,6 +133,18 @@ modulesInit:
bigcall SPIHW_Init
#endif
+#ifdef MODULES_SPI_SW
+ bigcall SPISW_Init
+#endif
+
+#ifdef MODULES_RAM_23LC512
+ bigcall RAM_23LC512_Init
+#endif
+
+#ifdef MODULES_EE_25LC256
+ bigcall EE_25LC256_Init
+#endif
+
#ifdef MODULES_LCD
bigcall LCD_Init
#endif
diff --git a/avr/modules/0BUILD b/avr/modules/0BUILD
index eb327de..d13cfa4 100644
--- a/avr/modules/0BUILD
+++ b/avr/modules/0BUILD
@@ -4,38 +4,47 @@
basetimer
+ beeper_simple
bmp280
+ bootloader
+ brightness
ccs811
clock
cny70
+ com2w
+ com2w_router
ds18b20
+ eeprom
+ f_keepup
+ f_stabilize
flash
+ heap
lcd
lcd2
led
motion
+ network
owimaster
+ ram
reed
+ rtc
sgp30
sgp40
si7021
sk6812
+ spi_hw
+ spi_sw
tcrt1000
timer
twimaster
- network
uart_bitbang
uart_bitbang2
- uart_irq
uart_fd
uart_hw
- bootloader
- f_keepup
+ uart_hw2
+ uart_irq
valsched
xram
- heap
- brightness
- rtc
diff --git a/avr/modules/eeprom/0BUILD b/avr/modules/eeprom/0BUILD
new file mode 100644
index 0000000..1ff18d5
--- /dev/null
+++ b/avr/modules/eeprom/0BUILD
@@ -0,0 +1,10 @@
+
+
+
+
+
+ 25LC256
+
+
+
+
diff --git a/avr/modules/eeprom/25LC256/0BUILD b/avr/modules/eeprom/25LC256/0BUILD
new file mode 100644
index 0000000..42e4c63
--- /dev/null
+++ b/avr/modules/eeprom/25LC256/0BUILD
@@ -0,0 +1,10 @@
+
+
+
+
+
+ main.asm
+
+
+
+
diff --git a/avr/modules/eeprom/25LC256/main.asm b/avr/modules/eeprom/25LC256/main.asm
new file mode 100644
index 0000000..9d04ade
--- /dev/null
+++ b/avr/modules/eeprom/25LC256/main.asm
@@ -0,0 +1,224 @@
+; ***************************************************************************
+; copyright : (C) 2026 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. *
+; ***************************************************************************
+
+#ifndef AQH_AVR_MODULES_EE_25LC256_MAIN_ASM
+#define AQH_AVR_MODULES_EE_25LC256_MAIN_ASM
+
+
+
+; ***************************************************************************
+; defs
+
+.equ EE_25LC256_SIZE = 32768
+
+.equ EE_25LC256_CMD_READ = 0x03
+.equ EE_25LC256_CMD_WRITE = 0x02
+.equ EE_25LC256_CMD_WRDI = 0x04
+.equ EE_25LC256_CMD_WREN = 0x06
+.equ EE_25LC256_CMD_RDSR = 0x05
+.equ EE_25LC256_CMD_WRSR = 0x01
+
+
+
+
+; ***************************************************************************
+; data
+
+.dseg
+
+
+
+; ***************************************************************************
+; code
+
+.cseg
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_Init @global
+;
+; @param X destination address
+
+EE_25LC256_Init:
+ sbi EEPROMCS_DDR, EEPROMCS_PIN ; EEPROMCS: output
+ sbi EEPROMCS_OUTPUT, EEPROMCS_PIN ; EEPROMCS high
+ sec
+ ret
+; @end
+
+
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_StartWriting @global
+;
+; @param X destination address
+; @clobbers r16-r19, r23
+
+EE_25LC256_StartWriting:
+ ldi r16, EE_25LC256_CMD_WRITE
+ rjmp ee25LC256StartTransfer ; (r16-r19, r23)
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_StartReading @global
+;
+; @param X source address
+; @clobbers r16-r19, r23
+
+EE_25LC256_StartReading:
+ ldi r16, EE_25LC256_CMD_READ
+ rjmp ee25LC256StartTransfer ; (r16-r19, r23)
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_EndTransfer @global
+;
+; @clobbers none
+
+EE_25LC256_EndTransfer:
+ sbi EEPROMCS_OUTPUT, EEPROMCS_PIN ; CS high
+ bigcall SPISW_MasterStop ; (none)
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_ReadBytes @global
+;
+; @param X source address
+; @param Y destination address
+; @param R25:r24 number of bytes to read
+; @clobbers r16-r19, r23-r25, Y
+
+EE_25LC256_ReadBytes:
+ rcall EE_25LC256_StartReading ; (r16-r19, r23)
+
+EE_25LC256_ReadBytes_loop:
+ ldi r16, 0xff
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ st Y+, r16
+ sbiw r25:r24, 1
+ brne EE_25LC256_ReadBytes_loop
+ rcall EE_25LC256_EndTransfer
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_WriteBytes @global
+;
+; @param X destination address
+; @param Y source address
+; @param R25:r24 number of bytes to write
+; @clobbers r16-r19, r23-r25, Y
+
+EE_25LC256_WriteBytes:
+ rcall EE_25LC256_WriteEnable ; (r16-r19, r23)
+ rcall EE_25LC256_StartWriting ; (r16-r19, r23)
+EE_25LC256_WriteBytes_loop:
+ ld r16, Y+
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ sbiw r25:r24, 1
+ brne EE_25LC256_WriteBytes_loop
+ rcall EE_25LC256_EndTransfer ; (none)
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_ReadStatusRegister
+;
+; @return r16 mode register
+; @clobbers r17-r19, r23
+
+EE_25LC256_ReadStatusRegister:
+ ldi r16, EE_25LC256_CMD_RDSR
+ rcall ee25LC256StartCommand
+ clr r16
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ push r16
+ rcall EE_25LC256_EndTransfer
+ pop r16
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine EE_25LC256_WriteEnable
+;
+; @clobbers r16-r19, r23
+
+EE_25LC256_WriteEnable:
+ ldi r16, EE_25LC256_CMD_WREN
+ rcall ee25LC256StartCommand ; (r16-r19, r23)
+ rcall EE_25LC256_EndTransfer ; (none)
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine ee25LC256StartTransfer
+;
+; @param r16 command
+; @param X address
+; @clobbers r16-r19, r23
+
+ee25LC256StartTransfer:
+ rcall ee25LC256StartCommand
+
+ ; send address
+ mov r16, xh
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ mov r16, xl
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine ee25LC256StartCommand
+;
+; @param r16 command
+; @clobbers r16-r19, r23
+
+ee25LC256StartCommand:
+ push r16
+ bigcall SPISW_MasterStart
+ pop r16
+ nop
+ sbi EEPROMCS_DDR, EEPROMCS_PIN ; CS: output
+ cbi EEPROMCS_OUTPUT, EEPROMCS_PIN ; CS low
+ nop
+
+ ; send command
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+
+ ret
+; @end
+
+
+
+
+
+#endif
+
diff --git a/avr/modules/ram/0BUILD b/avr/modules/ram/0BUILD
new file mode 100644
index 0000000..cb0f27d
--- /dev/null
+++ b/avr/modules/ram/0BUILD
@@ -0,0 +1,10 @@
+
+
+
+
+
+ 23LC512
+
+
+
+
diff --git a/avr/modules/ram/23LC512/0BUILD b/avr/modules/ram/23LC512/0BUILD
new file mode 100644
index 0000000..68686d6
--- /dev/null
+++ b/avr/modules/ram/23LC512/0BUILD
@@ -0,0 +1,9 @@
+
+
+
+
+
+ main.asm
+
+
+
diff --git a/avr/modules/ram/23LC512/main.asm b/avr/modules/ram/23LC512/main.asm
new file mode 100644
index 0000000..f9ca8ba
--- /dev/null
+++ b/avr/modules/ram/23LC512/main.asm
@@ -0,0 +1,286 @@
+; ***************************************************************************
+; copyright : (C) 2026 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. *
+; ***************************************************************************
+
+#ifndef AQH_AVR_MODULES_RAM_23LC512_MAIN_ASM
+#define AQH_AVR_MODULES_RAM_23LC512_MAIN_ASM
+
+
+
+; ***************************************************************************
+; defs
+
+.equ RAM_23LC512_LASTADDR = 65535
+.equ RAM_23LC512_PATTERNSIZE = 0
+
+.equ RAM_23LC512_CMD_READ = 0x03
+.equ RAM_23LC512_CMD_WRITE = 0x02
+.equ RAM_23LC512_CMD_RDMR = 0x05
+.equ RAM_23LC512_CMD_WRMR = 0x01
+
+
+
+
+; ***************************************************************************
+; data
+
+.dseg
+
+
+
+; ***************************************************************************
+; code
+
+.cseg
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_Init @global
+;
+; @param X destination address
+
+RAM_23LC512_Init:
+ sbi RAMCS_DDR, RAMCS_PIN ; RAMCS: output
+ sbi RAMCS_OUTPUT, RAMCS_PIN ; RAMCS high
+ sec
+ ret
+; @end
+
+
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_StartWriting @global
+;
+; @param X destination address
+; @clobbers r16-r19, r23
+
+RAM_23LC512_StartWriting:
+ ldi r16, RAM_23LC512_CMD_WRITE
+ rjmp ram23LC512StartTransfer ; (r16-r19, r23)
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_StartReading @global
+;
+; @param X source address
+; @clobbers r16-r19, r23
+
+RAM_23LC512_StartReading:
+ ldi r16, RAM_23LC512_CMD_READ
+ rjmp ram23LC512StartTransfer ; (r16-r19, r23)
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_EndTransfer @global
+;
+
+RAM_23LC512_EndTransfer:
+ sbi RAMCS_OUTPUT, RAMCS_PIN ; CS high
+ bigcall SPISW_MasterStop
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_ReadBytes @global
+;
+; @param X source address
+; @param Y destination address
+; @param R25:r24 number of bytes to read
+; @clobbers r16-r19, r23-r25
+
+RAM_23LC512_ReadBytes:
+ rcall RAM_23LC512_StartReading ; (r16-r19, r23)
+
+RAM_23LC512_ReadBytes_loop:
+ ldi r16, 0xff
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ st Y+, r16
+ sbiw r25:r24, 1
+ brne RAM_23LC512_ReadBytes_loop
+ rcall RAM_23LC512_EndTransfer
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_WriteBytes @global
+;
+; @param X destination address
+; @param Y source address
+; @param R25:r24 number of bytes to write
+; @clobbers r16-r19, r23-r25
+
+RAM_23LC512_WriteBytes:
+ rcall RAM_23LC512_StartWriting ; (r16-r19, r23)
+
+RAM_23LC512_WriteBytes_loop:
+ ld r16, Y+
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ sbiw r25:r24, 1
+ brne RAM_23LC512_WriteBytes_loop
+ rcall RAM_23LC512_EndTransfer
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_Fill @global
+;
+; @param X destination address
+; @param R16 byte to write
+; @param R25:r24 number of bytes to write
+; @clobbers r16-r19, r22-r25
+
+RAM_23LC512_Fill:
+ mov r22, r16
+ rcall RAM_23LC512_StartWriting ; (r16-r19, r23)
+
+RAM_23LC512_Fill_loop:
+ mov r16, r22
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ sbiw r25:r24, 1
+ brne RAM_23LC512_Fill_loop
+ rcall RAM_23LC512_EndTransfer
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_WritePattern @global
+;
+; @clobbers r16-r19, r23-r25
+
+RAM_23LC512_WritePattern:
+ clr xl
+ clr xh
+ rcall RAM_23LC512_StartWriting ; (r16-r19, r23)
+ ldi r24, LOW(RAM_23LC512_PATTERNSIZE)
+ ldi r25, HIGH(RAM_23LC512_PATTERNSIZE)
+ clr xl
+ clr xh
+RAM_23LC512_WritePattern_loop:
+ mov r16, xh
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ adiw xh:xl, 1
+ sbiw r25:r24, 1
+ brne RAM_23LC512_WritePattern_loop
+ rcall RAM_23LC512_EndTransfer
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_ReadPattern @global
+;
+; @clobbers r16-r19, r23-r25
+
+RAM_23LC512_ReadPattern:
+ clr xl
+ clr xh
+ rcall RAM_23LC512_StartReading ; (r16-r19, r23)
+ ldi r24, LOW(RAM_23LC512_PATTERNSIZE)
+ ldi r25, HIGH(RAM_23LC512_PATTERNSIZE)
+ clr xl
+ clr xh
+RAM_23LC512_ReadPattern_loop:
+ ldi r16, 0xff
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ cp r16, xh
+ clc
+ brne RAM_23LC512_ReadPattern_ret
+ adiw xh:xl, 1
+ sbiw r25:r24, 1
+ brne RAM_23LC512_ReadPattern_loop
+ rcall RAM_23LC512_EndTransfer
+ sec
+RAM_23LC512_ReadPattern_ret:
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine RAM_23LC512_ReadModeRegister
+;
+; @return r16 mode register
+; @clobbers r17-r19, r23
+
+RAM_23LC512_ReadModeRegister:
+ ldi r16, RAM_23LC512_CMD_RDMR
+ rcall ram23LC512StartCommand
+ clr r16
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ push r16
+ rcall RAM_23LC512_EndTransfer
+ pop r16
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine ram23LC512StartTransfer
+;
+; @param r16 command
+; @param X address
+; @clobbers r16-r19, r23
+
+ram23LC512StartTransfer:
+ rcall ram23LC512StartCommand
+
+ ; send address
+ mov r16, xh
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+ mov r16, xl
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine ram23LC512StartCommand
+;
+; @param r16 command
+; @clobbers r16-r19, r23
+
+ram23LC512StartCommand:
+ push r16
+ bigcall SPISW_MasterStart
+ pop r16
+ nop
+ sbi RAMCS_DDR, RAMCS_PIN ; CS: output
+ cbi RAMCS_OUTPUT, RAMCS_PIN ; CS low
+ nop
+
+ ; send command
+ bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
+
+ ret
+; @end
+
+
+
+
+
+#endif
+
diff --git a/avr/modules/spi_sw/0BUILD b/avr/modules/spi_sw/0BUILD
new file mode 100644
index 0000000..febd367
--- /dev/null
+++ b/avr/modules/spi_sw/0BUILD
@@ -0,0 +1,11 @@
+
+
+
+
+
+ main.asm
+
+
+
+
+
diff --git a/avr/modules/spi_sw/main.asm b/avr/modules/spi_sw/main.asm
new file mode 100644
index 0000000..72a2631
--- /dev/null
+++ b/avr/modules/spi_sw/main.asm
@@ -0,0 +1,131 @@
+; ***************************************************************************
+; 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. *
+; ***************************************************************************
+
+
+; ***************************************************************************
+; macros
+
+; @param @0 register to use
+
+
+
+; ***************************************************************************
+; defines
+
+
+
+; ***************************************************************************
+; data
+
+.dseg
+
+
+
+; ***************************************************************************
+; code
+
+.cseg
+
+
+
+; ---------------------------------------------------------------------------
+; @routine SPISW_Init @global
+;
+
+SPISW_Init:
+ sec
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine SPISW_MasterStart @global
+;
+; Start SPI software master.
+; @clobbers none
+
+SPISW_MasterStart:
+ ; setup pins
+ sbi SPISW_MOSI_DDR, SPISW_MOSI_PIN ; MOSI: output
+ cbi SPISW_MISO_DDR, SPISW_MISO_PIN ; MISO: input
+ sbi SPISW_SCK_DDR, SPISW_SCK_PIN ; SCK: output
+ cbi SPISW_SCK_OUTPUT, SPISW_SCK_PIN ; clock low
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine SPISW_MasterStop @global
+;
+; Stop SPI software master. Put all ports to high-Z mode.
+; @clobbers none
+
+SPISW_MasterStop:
+ ; setup pins
+ cbi SPISW_MOSI_DDR, SPISW_MOSI_PIN ; MOSI: input
+ cbi SPISW_MOSI_OUTPUT, SPISW_MOSI_PIN ; disable pullup
+ cbi SPISW_MISO_DDR, SPISW_MISO_PIN ; MISO: input
+ cbi SPISW_MISO_OUTPUT, SPISW_MISO_PIN ; disable pullup
+ cbi SPISW_SCK_DDR, SPISW_SCK_PIN ; SCK: input
+ cbi SPISW_SCK_OUTPUT, SPISW_SCK_PIN ; disable pullup
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine SPIHW_MasterExchangeByteMode0 @global
+;
+; @param r16 byte to send
+; @return r16 byte received
+; @clobbers r17, r18, r19, r23
+
+SPISW_MasterExchangeByteMode0:
+ push r15
+ inr r15, SREG
+ cli
+
+ ldi r23, 8
+SPISW_MasterExchangeByteMode0_loop:
+ ; clock low
+ cbi SPISW_SCK_OUTPUT, SPISW_SCK_PIN
+ nop
+
+ ; write MOSI
+ sbrs r16, 7
+ cbi SPISW_MOSI_OUTPUT, SPISW_MOSI_PIN
+ sbrc r16, 7
+ sbi SPISW_MOSI_OUTPUT, SPISW_MOSI_PIN
+ nop
+ lsl r16
+
+ ; clock high
+ sbi SPISW_SCK_OUTPUT, SPISW_SCK_PIN
+ nop
+
+ ; read MISO
+ lsl r17
+ sbic SPISW_MISO_INPUT, SPISW_MISO_PIN
+ inc r17
+ dec r23
+ brne SPISW_MasterExchangeByteMode0_loop
+ mov r16, r17
+
+ outr SREG, r15
+ pop r15
+ ret
+; @end
+
+
+
+
+
+