; *************************************************************************** ; copyright : (C) 2024 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. * ; *************************************************************************** ; *************************************************************************** ; defs .equ DS18B20_ROMCMD_READROM = 0x33 .equ DS18B20_ROMCMD_SKIPROM = 0xcc .equ DS18B20_FNCMD_CONVERT = 0x44 .equ DS18B20_FNCMD_READSCRATCHPAD = 0xbe .equ DS18B20_FLAGS_CONV_STARTED = 0x01 .equ DS18B20_FLAGS_CONV_UPDATED = 0x02 .equ DS18B20_POLYNOMIAL = 0x8c .equ DS18B20_INTERVAL_SECS = 30 ; *************************************************************************** ; data .dseg ds18b20DataBegin: ds18b20Flags: .byte 1 ds18b20Timer: .byte 1 ds18b20DataBuffer: .byte 9 ds18b20DataTemp: .byte 2 ds18b20DataEnd: ; *************************************************************************** ; code .cseg DS18B20_BEGIN: ; --------------------------------------------------------------------------- ; @routine Ds18b20_Init @global ; ; @return CFLAG set if okay, cleared on error ; @clobbers r16, r17, X Ds18b20_Init: ; preset SRAM data area ldi xh, HIGH(ds18b20DataBegin) ldi xl, LOW(ds18b20DataBegin) clr r16 ldi r17, (ds18b20DataEnd-ds18b20DataBegin) rcall Utils_FillSram ; (r17, x) ret ; @end ; --------------------------------------------------------------------------- ; @routine Ds18b20_Fini @global Ds18b20_Fini: ret ; @end ; --------------------------------------------------------------------------- ; @routine Ds18b20_OnEverySecond @global Ds18b20_OnEverySecond: lds r16, ds18b20Timer subi r16, 1 brcc Ds18b20_OnEverySecond_store ldi r16, DS18B20_INTERVAL_SECS Ds18b20_OnEverySecond_store: sts ds18b20Timer, r16 cpi r16, 28 breq Ds18b20_OnEverySecond_startConversion cpi r16, 2 breq Ds18b20_OnEverySecond_readResult rjmp Ds18b20_OnEverySecond_end Ds18b20_OnEverySecond_startConversion: push r15 in r15, SREG cli ldi r16, DS18B20_FNCMD_CONVERT rcall ds18b20SendCommand rjmp Ds18b20_OnEverySecond_popr15ret Ds18b20_OnEverySecond_readResult: push r15 in r15, SREG cli ldi xl, LOW(ds18b20DataBuffer) ldi xh, HIGH(ds18b20DataBuffer) rcall ds18b20ReadScratchPad brcc Ds18b20_OnEverySecond_popr15ret ld r16, X+ ; copy temp from scratchpad sts ds18b20DataTemp, r16 ld r16, X+ sts ds18b20DataTemp+1, r16 lds r16, ds18b20Flags andi r16, ~DS18B20_FLAGS_CONV_STARTED ori r16, DS18B20_FLAGS_CONV_UPDATED sts ds18b20Flags, r16 rjmp Ds18b20_OnEverySecond_popr15ret Ds18b20_OnEverySecond_popr15ret: out SREG, r15 pop r15 Ds18b20_OnEverySecond_end: ret ; @end ; --------------------------------------------------------------------------- ; @routine ds18b20SendCommand @global ; ; Reset bus, send SKIP ROM and send command. ; Cave: Needs interrupts to be disabled! ; ; @param r16 command to send ; @clobbers r18 (r21, r22) ds18b20SendCommand: mov r18, r16 rcall OwiMaster_Reset ; (r21, r22) tst r16 ; presence detected? breq ds18b20SendCommand_error ; nope, jump ldi r16, DS18B20_ROMCMD_SKIPROM ; skip rom rcall OwiMaster_SendByte ; (r21, r22) mov r16, r18 ; command to send rcall OwiMaster_SendByte ; (r21, r22) sec ret ds18b20SendCommand_error: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine ds18b20ReadRom @global ; ; Send READ ROM and read result into buffer. ; Cave: Needs interrupts to be disabled! ; ; @return CFLAG set if okay, cleared on error ; @return X points directly behind the last byte received ; @param X pointer to SDRAM to receive 8 bytes ; @clobbers r16, r18, r19, r23, X (r17, r20, r21, r22) ds18b20ReadRom: rcall OwiMaster_Reset ; (r21, r22) tst r16 ; presence detected? breq ds18b20ReadRom_error ; nope, jump ldi r16, DS18B20_ROMCMD_READROM rcall OwiMaster_SendByte ; (r21, r22) ldi r23, 8 ds18b20ReadRom_loop1: Utils_WaitNanoSecs 10000, 0, r22 rcall OwiMaster_RecvByte ; (r21, r22) st X+, r16 dec r23 brne ds18b20ReadRom_loop1 sbiw xh:xl, 8 ldi r18, 8 ldi r19, DS18B20_POLYNOMIAL rcall crc8Calc ; (R16, R17, R18, R20, R21, X) tst r16 brne ds18b20ReadRom_error sec ret ds18b20ReadRom_error: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine ds18b20ReadScratchPad ; ; Send SKIP_ROM, READ_SCRATCHPAD and read 9 byte result into buffer. ; ; Cave: Needs interrupts to be disabled! ; ; @return CFLAG set if okay, cleared on error ; @return X unchanged if CFLAG set (otherwise clobbered) ; @param X pointer to SDRAM to receive 8 bytes ; @clobbers r16, r18, r19, r23, X (r17, r20, r21, r22) ds18b20ReadScratchPad: ldi r16, DS18B20_FNCMD_READSCRATCHPAD rcall ds18b20SendCommand brcc ds18b20ReadScratchPad_error ldi r23, 9 ds18b20ReadScratchPad_loop1: Utils_WaitNanoSecs 10000, 0, r22 rcall OwiMaster_RecvByte ; (r21, r22) st X+, r16 dec r23 brne ds18b20ReadScratchPad_loop1 sbiw xh:xl, 9 ldi r18, 9 ldi r19, DS18B20_POLYNOMIAL rcall crc8Calc ; (R16, R17, R18, R20, R21, X) tst r16 brne ds18b20ReadScratchPad_error sbiw xh:xl, 9 sec ret ds18b20ReadScratchPad_error: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine Ds18b20_GetValue @global ; ; @return CFLAG set if value available, cleared otherwise ; @return R19:R18 value ; @return R21:R20 denom (e.g. 100, meaning value must be divided by 100) ; @clobbers R16 Ds18b20_GetValue: lds r16, ds18b20Flags andi r16, DS18B20_FLAGS_CONV_UPDATED breq Ds18b20_GetValue_done lds r18, ds18b20DataTemp ; value lds r19, ds18b20DataTemp+1 ldi r20, 16 ; denominator clr r21 sec Ds18b20_GetValue_done: ret ; @end DS18B20_END: .equ MODULE_SIZE_DS18B20 = DS18B20_END-DS18B20_BEGIN