; *************************************************************************** ; copyright : (C) 2023 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. * ; *************************************************************************** ; *************************************************************************** ; data .dseg utilsDataBegin: utilsSeed: .byte 2 utilsDataEnd: ; *************************************************************************** ; code .cseg UTILS_BEGIN: utilsDateString: .db "%YEAR%-%MONTH%-%DAY%-%HOUR%:%MINUTE%", 0, 0 ; --------------------------------------------------------------------------- ; Utils_Init ; ; IN: ; OUT: ; - CFLAG: set if okay, clear on error ; USED: R16, R17, R18, R19, X, (R20, R21, R24, R25, X, Z) Utils_Init: rcall utilsSetupSeed ; (R16, R18, R19, R20, R21, R24, R25, X, Z) ; preset SRAM data area ldi xh, HIGH(utilsDataBegin) ldi xl, LOW(utilsDataBegin) clr r16 ldi r17, (utilsDataEnd-utilsDataBegin) rcall Utils_FillSram ; (r17, x) sts utilsSeed, r18 sts utilsSeed+1, r19 sec ret ; --------------------------------------------------------------------------- ; setup seed ; ; IN: ; OUT: ; REGS: R16, R18, R19, R20, R21, R24, R25, X, Z utilsSetupSeed: rcall Utils_ReadSeed mov r20, r18 mov r21, r19 ; default initial seed ldi r18, 0xe1 ldi r19, 0xac ; work stored seed into it mov r16, r20 rcall utilsWorkByteIntoSeed mov r16, r21 rcall utilsWorkByteIntoSeed ; work date string into seed ldi zl, LOW(utilsDateString*2) ldi zh, HIGH(utilsDateString*2) rcall utilsWorkProgStringIntoSeed ; (R16, Z) ; work sram content into seed rcall utilsWorkSramContentIntoSeed ; (R16, R24, R25, X) ; store seed in EEPROM rcall Utils_WriteSeed ; (R16, R17, X) ret ; --------------------------------------------------------------------------- ; utilsWorkProgStringIntoSeed ; ; IN: ; - Z : pointer to string to work into seed ; - R18: low byte of current seed ; - R19: high byte of current seed ; OUT: ; - R18: low byte of updated seed ; - R19: high byte of updated seed ; USED: R16, Z utilsWorkProgStringIntoSeed: lpm r16, Z+ tst r16 breq utilsWorkProgStringIntoSeed_done rcall utilsWorkByteIntoSeed rjmp utilsWorkProgStringIntoSeed utilsWorkProgStringIntoSeed_done: ret ; --------------------------------------------------------------------------- ; utilsWorkSramContentIntoSeed ; IN: ; - Z : pointer to string to work into seed ; - R18: low byte of current seed ; - R19: high byte of current seed ; OUT: ; - R18: low byte of updated seed ; - R19: high byte of updated seed ; USED: R16, R24, R25, X utilsWorkSramContentIntoSeed: ldi xl, LOW(SRAM_START) ldi xh, HIGH(SRAM_START) ldi r24, LOW(RAMEND-SRAM_START) ldi r25, HIGH(RAMEND-SRAM_START) utilsWorkSramContentIntoSeed_loop: ld r16, X+ rcall utilsWorkByteIntoSeed sbiw r25:r24, 1 brne utilsWorkSramContentIntoSeed_loop ret ; --------------------------------------------------------------------------- ; utilsWorkByteIntoSeed ; ; IN: ; - R16: byte to work into the seed ; - R18: low byte of current seed ; - R19: high byte of current seed ; OUT: ; - R18: low byte of updated seed ; - R19: high byte of updated seed ; USED: utilsWorkByteIntoSeed: eor r18, r16 clc sbrc r19, 7 sec ; only executed if bit 7 is set in r19 rol r18 rol r19 ret ; --------------------------------------------------------------------------- ; Utils_Fini ; ; IN: ; OUT: ; - CFLAG: set if okay, clear on error ; USED: R16, R17, R18, X, Y Utils_Fini: sec ret ; --------------------------------------------------------------------------- ; @routine Utils_FillSram @global ; ; @return X points directly behind filled memory ; @param X pointer to SRAM to fill ; @param r16 value to fill the SRAM with ; @param r17 size of area to fill ; @clobbers r17, X Utils_FillSram: tst r17 breq Utils_FillSram_end Utils_FillSram_loop: st x+, r16 dec r17 brne Utils_FillSram_loop Utils_FillSram_end: ret ; @end ; --------------------------------------------------------------------------- ; Increment a 32 bit counter at the address given by X. ; IN: ; - X: Address of the 4 byte counter (1. byte is LSB) ; OUT: ; - nothing ; MODIFIED REGISTERS: r18, r19, r20, r21, 22 Utils_IncrementCounter32: ld r18, x+ ld r19, x+ ld r20, x+ ld r21, x ldi r22, 1 add r18, r22 clr r22 ; doesn't affect carry flag adc r19, r22 adc r20, r22 adc r21, r22 st x, r21 st -x, r20 st -x, r19 st -x, r18 ret ; --------------------------------------------------------------------------- ; Increment a 16 bit counter at the address given by X. ; IN: ; - X: Address of the 2 byte counter (1. byte is LSB) ; OUT: ; - nothing ; MODIFIED REGISTERS: r18, r19, 22 Utils_IncrementCounter16: ld r18, x+ ld r19, x ldi r22, 1 add r18, r22 clr r22 ; doesn't affect carry flag adc r19, r22 st x, r19 st -x, r18 ret ; --------------------------------------------------------------------------- ; Utils_ReadEepromIncr ; ; Read a byte from EEPROM (see example in ATtiny24/44/84 manual p.19). ; ; IN: ; - X: EEPROM Address to read from ; OUT: ; - R16: byte read ; - X: EEPROM Address incremented ; MODIFIED REGISTERS: R16 Utils_ReadEepromIncr: .ifdef EEPE sbic EECR, EEPE ; wait for previous write to complete (if any) .else sbic EECR, EEWE ; wait for previous write to complete (if any) .endif rjmp Utils_ReadEepromIncr out EEARH, xh ; set EEPROM address out EEARL, xl sbi EECR, EERE ; start EEPROM read by writing EERE in r16, EEDR ; read data from data register adiw xh:xl, 1 ret ; --------------------------------------------------------------------------- ; Utils_WriteEepromIncr ; ; Write a byte to EEPROM (see example in ATtiny24/44/84 manual p.18). ; ; IN: ; - R16: byte to write ; - X: EEPROM Address to write to ; OUT: ; - X: EEPROM Address incremented ; MODIFIED REGISTERS: R17 Utils_WriteEepromIncr: .ifdef EEPE sbic EECR, EEPE ; wait for previous write to complete (if any) .else sbic EECR, EEWE ; wait for previous write to complete (if any) .endif rjmp Utils_WriteEepromIncr .ifdef EEPM1 ldi r17, (0<