added modules for SGP30/40.
This commit is contained in:
@@ -53,6 +53,13 @@ AppReportSensors_Fini:
|
|||||||
;
|
;
|
||||||
|
|
||||||
AppReportSensors_OnEverySecond:
|
AppReportSensors_OnEverySecond:
|
||||||
|
in r15, SREG
|
||||||
|
push r15
|
||||||
|
cli
|
||||||
|
rcall AppReportSensors_OnEverySecond_noIrqs
|
||||||
|
out SREG, r15
|
||||||
|
ret
|
||||||
|
AppReportSensors_OnEverySecond_noIrqs:
|
||||||
lds r16, reportSensorTimer
|
lds r16, reportSensorTimer
|
||||||
inc r16
|
inc r16
|
||||||
cpi r16, APP_REPORT_SENSORS_INTERVAL_SECS
|
cpi r16, APP_REPORT_SENSORS_INTERVAL_SECS
|
||||||
@@ -60,6 +67,13 @@ AppReportSensors_OnEverySecond:
|
|||||||
clr r16
|
clr r16
|
||||||
AppReportSensors_OnEverySecond_store:
|
AppReportSensors_OnEverySecond_store:
|
||||||
sts reportSensorTimer, r16
|
sts reportSensorTimer, r16
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP30
|
||||||
|
; push r16
|
||||||
|
; rcall SGP30_Measure
|
||||||
|
; pop r16
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULES_SI7021
|
#ifdef MODULES_SI7021
|
||||||
cpi r16, 1
|
cpi r16, 1
|
||||||
breq AppReportSensors_OnEverySecond_measureValue1
|
breq AppReportSensors_OnEverySecond_measureValue1
|
||||||
@@ -70,11 +84,30 @@ AppReportSensors_OnEverySecond_store:
|
|||||||
cpi r16, 49
|
cpi r16, 49
|
||||||
breq AppReportSensors_OnEverySecond_sendValue2
|
breq AppReportSensors_OnEverySecond_sendValue2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP40
|
||||||
|
cpi r16, 27
|
||||||
|
breq AppReportSensors_OnEverySecond_measureValue4
|
||||||
|
cpi r16, 55
|
||||||
|
breq AppReportSensors_OnEverySecond_sendValue4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP30
|
||||||
|
cpi r16, 29
|
||||||
|
breq AppReportSensors_OnEverySecond_measureValue5
|
||||||
|
cpi r16, 57
|
||||||
|
breq AppReportSensors_OnEverySecond_sendValue5
|
||||||
|
cpi r16, 59
|
||||||
|
breq AppReportSensors_OnEverySecond_sendValue6
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULES_DS18B20
|
#ifdef MODULES_DS18B20
|
||||||
cpi r16, 9
|
cpi r16, 9
|
||||||
breq AppReportSensors_OnEverySecond_sendValue3
|
breq AppReportSensors_OnEverySecond_sendValue3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
#ifdef MODULES_SI7021
|
#ifdef MODULES_SI7021
|
||||||
AppReportSensors_OnEverySecond_measureValue1:
|
AppReportSensors_OnEverySecond_measureValue1:
|
||||||
rjmp SI7021_MeasureTemp
|
rjmp SI7021_MeasureTemp
|
||||||
@@ -85,10 +118,29 @@ AppReportSensors_OnEverySecond_sendValue1:
|
|||||||
AppReportSensors_OnEverySecond_sendValue2:
|
AppReportSensors_OnEverySecond_sendValue2:
|
||||||
rjmp SI7021_SendHumidity
|
rjmp SI7021_SendHumidity
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODULES_DS18B20
|
#ifdef MODULES_DS18B20
|
||||||
AppReportSensors_OnEverySecond_sendValue3:
|
AppReportSensors_OnEverySecond_sendValue3:
|
||||||
rjmp Ds18b20_SendTemperature
|
rjmp Ds18b20_SendTemperature
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP40
|
||||||
|
AppReportSensors_OnEverySecond_measureValue4:
|
||||||
|
rjmp SGP40_MeasureRawSignal
|
||||||
|
AppReportSensors_OnEverySecond_sendValue4:
|
||||||
|
rjmp SGP40_SendTVOC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP30
|
||||||
|
AppReportSensors_OnEverySecond_measureValue5:
|
||||||
|
rjmp SGP30_Measure
|
||||||
|
AppReportSensors_OnEverySecond_sendValue5:
|
||||||
|
rjmp SGP30_SendTVOC
|
||||||
|
ret
|
||||||
|
AppReportSensors_OnEverySecond_sendValue6:
|
||||||
|
rjmp SGP30_SendCO2
|
||||||
|
#endif
|
||||||
|
|
||||||
; @end
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,20 @@
|
|||||||
.include "common/multiply.asm"
|
.include "common/multiply.asm"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP30
|
||||||
|
.include "modules/sgp30/main.asm"
|
||||||
|
#ifdef MODULES_NETWORK
|
||||||
|
.include "modules/sgp30/send.asm"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP40
|
||||||
|
.include "modules/sgp40/main.asm"
|
||||||
|
#ifdef MODULES_NETWORK
|
||||||
|
.include "modules/sgp40/send.asm"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULES_OWI_MASTER
|
#ifdef MODULES_OWI_MASTER
|
||||||
.include "modules/owimaster/main.asm"
|
.include "modules/owimaster/main.asm"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ sysOnEveryMinute:
|
|||||||
#ifdef APPS_STATS
|
#ifdef APPS_STATS
|
||||||
rcall AppStats_OnEveryMinute
|
rcall AppStats_OnEveryMinute
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rjmp onEveryMinute
|
rjmp onEveryMinute
|
||||||
; @end
|
; @end
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,14 @@ initModules:
|
|||||||
rcall SI7021_Init
|
rcall SI7021_Init
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP30
|
||||||
|
rcall SGP30_Init
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULES_SGP40
|
||||||
|
rcall SGP40_Init
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULES_DS18B20
|
#ifdef MODULES_DS18B20
|
||||||
rcall Ds18b20_Init
|
rcall Ds18b20_Init
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -103,6 +103,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; SGB 30
|
||||||
|
|
||||||
|
.equ SGP30_ADDR = 0x58
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; SGB 40
|
||||||
|
|
||||||
|
.equ SGP40_ADDR = 0x59
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; 1-Wire Master
|
; 1-Wire Master
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -69,6 +69,8 @@
|
|||||||
;#define MODULES_LCD
|
;#define MODULES_LCD
|
||||||
;#define LCD_MINIMAL_FONT
|
;#define LCD_MINIMAL_FONT
|
||||||
#define MODULES_SI7021
|
#define MODULES_SI7021
|
||||||
|
#define MODULES_SGP30
|
||||||
|
;#define MODULES_SGP40
|
||||||
;#define MODULES_STATS
|
;#define MODULES_STATS
|
||||||
;#define MODULES_OWI_MASTER
|
;#define MODULES_OWI_MASTER
|
||||||
;#define MODULES_DS18B20
|
;#define MODULES_DS18B20
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
motion
|
motion
|
||||||
owimaster
|
owimaster
|
||||||
reed
|
reed
|
||||||
|
sgp30
|
||||||
|
sgp40
|
||||||
si7021
|
si7021
|
||||||
sk6812
|
sk6812
|
||||||
stats
|
stats
|
||||||
|
|||||||
12
avr/modules/sgp30/0BUILD
Normal file
12
avr/modules/sgp30/0BUILD
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml?>
|
||||||
|
|
||||||
|
<gwbuild>
|
||||||
|
|
||||||
|
<extradist>
|
||||||
|
main.asm
|
||||||
|
send.asm
|
||||||
|
</extradist>
|
||||||
|
|
||||||
|
</gwbuild>
|
||||||
|
|
||||||
|
|
||||||
327
avr/modules/sgp30/main.asm
Normal file
327
avr/modules/sgp30/main.asm
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
; ***************************************************************************
|
||||||
|
; 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. *
|
||||||
|
; ***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ***************************************************************************
|
||||||
|
; defines
|
||||||
|
|
||||||
|
.equ SGP30_FLAGS_PRESENT_BIT = 7
|
||||||
|
.equ SGP30_FLAGS_DATAVALID_BIT = 6
|
||||||
|
|
||||||
|
|
||||||
|
.equ SGP30_CMD_INIT = 0x2003
|
||||||
|
.equ SGP30_CMD_MEASURE = 0x2008
|
||||||
|
|
||||||
|
.equ SGP30_VALUE_TVOC = 0x01
|
||||||
|
.equ SGP30_VALUE_CO2 = 0x02
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ***************************************************************************
|
||||||
|
; data
|
||||||
|
|
||||||
|
.dseg
|
||||||
|
|
||||||
|
sgp30DataBegin:
|
||||||
|
sgp30Flags: .byte 1
|
||||||
|
sgp30LastCo2: .byte 2
|
||||||
|
sgp30LastTvoc: .byte 2
|
||||||
|
sgp30DataEnd:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ***************************************************************************
|
||||||
|
; code
|
||||||
|
|
||||||
|
.cseg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; SGP30_Init
|
||||||
|
;
|
||||||
|
|
||||||
|
SGP30_Init:
|
||||||
|
ldi xh, HIGH(sgp30DataBegin)
|
||||||
|
ldi xl, LOW(sgp30DataBegin)
|
||||||
|
clr r16
|
||||||
|
ldi r17, (sgp30DataEnd-sgp30DataBegin)
|
||||||
|
rcall Utils_FillSram
|
||||||
|
|
||||||
|
rjmp sg30InitIfNeeded
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; SGP30_Fini
|
||||||
|
;
|
||||||
|
|
||||||
|
SGP30_Fini:
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine SGP30_GetValue @global
|
||||||
|
;
|
||||||
|
; @param R16 value to get (SI7021_VALUE_TEMP, SI7021_VALUE_HUMIDITY)
|
||||||
|
; @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
|
||||||
|
|
||||||
|
SGP30_GetValue:
|
||||||
|
lds r18, sgp30Flags
|
||||||
|
andi r18, (1<<SGP30_FLAGS_DATAVALID_BIT)
|
||||||
|
breq SGP30_GetValue_clcRet
|
||||||
|
cpi r16, SGP30_VALUE_TVOC
|
||||||
|
breq SGP30_GetValue_retTvoc
|
||||||
|
cpi r16, SGP30_VALUE_CO2
|
||||||
|
breq SGP30_GetValue_retCo2
|
||||||
|
SGP30_GetValue_clcRet:
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
SGP30_GetValue_retTvoc:
|
||||||
|
lds r18, sgp30LastTvoc
|
||||||
|
lds r19, sgp30LastTvoc+1
|
||||||
|
ldi r20, 1
|
||||||
|
clr r21
|
||||||
|
rjmp SGP30_GetValue_secRet
|
||||||
|
SGP30_GetValue_retCo2:
|
||||||
|
lds r18, sgp30LastCo2
|
||||||
|
lds r19, sgp30LastCo2+1
|
||||||
|
ldi r20, 1
|
||||||
|
clr r21
|
||||||
|
SGP30_GetValue_secRet:
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine sg30InitIfNeeded
|
||||||
|
;
|
||||||
|
; Expects interrupts being disabled!
|
||||||
|
;
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @clobbers R16 (R17, R18, R22)
|
||||||
|
|
||||||
|
sg30InitIfNeeded:
|
||||||
|
lds r16, sgp30Flags
|
||||||
|
andi r16, (1<<SGP30_FLAGS_PRESENT_BIT)
|
||||||
|
breq sg30InitIfNeeded_doit
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
sg30InitIfNeeded_doit:
|
||||||
|
; check presence
|
||||||
|
rcall sgp30CheckPresence ; (R16, R17, R18, R22)
|
||||||
|
brcc sg30InitIfNeeded_error
|
||||||
|
; call init function
|
||||||
|
rcall sgp30Init
|
||||||
|
brcc sg30InitIfNeeded_error
|
||||||
|
lds r16, sgp30Flags
|
||||||
|
ori r16, (1<<SGP30_FLAGS_PRESENT_BIT)
|
||||||
|
sts sgp30Flags, r16
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
sg30InitIfNeeded_error:
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine sgp30CheckPresence
|
||||||
|
;
|
||||||
|
; Expects interrupts being disabled!
|
||||||
|
;
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @clobbers R16 (R17, R18, R22)
|
||||||
|
|
||||||
|
sgp30CheckPresence:
|
||||||
|
ldi r16, (SGP30_ADDR*2) ; write access
|
||||||
|
rjmp twiCheckPresence ; (R16, R17, R18, R22)
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine SGP30_Measure
|
||||||
|
;
|
||||||
|
; Expects interrupts being disabled!
|
||||||
|
;
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @clobbers R16, R17, R18, R19, R20, R21, R22
|
||||||
|
|
||||||
|
SGP30_Measure:
|
||||||
|
in r15, SREG
|
||||||
|
push r15
|
||||||
|
cli
|
||||||
|
lds r16, sgp30Flags
|
||||||
|
andi r16, (1<<SGP30_FLAGS_PRESENT_BIT)
|
||||||
|
breq SGP30_Measure_error
|
||||||
|
rcall sgp30Measure ; R19:R18=TVOC, R21:R20=CO2eq
|
||||||
|
brcc SGP30_Measure_error
|
||||||
|
lds r17, sgp30Flags
|
||||||
|
ori r17, (1<<SGP30_FLAGS_DATAVALID_BIT)
|
||||||
|
sts sgp30LastTvoc, r18
|
||||||
|
sts sgp30LastTvoc+1, r19
|
||||||
|
sts sgp30LastCo2, r20
|
||||||
|
sts sgp30LastCo2+1, r21
|
||||||
|
sts sgp30Flags, r17
|
||||||
|
SGP30_Measure_done:
|
||||||
|
pop r15
|
||||||
|
out SREG, r15
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
SGP30_Measure_error:
|
||||||
|
pop r15
|
||||||
|
out SREG, r15
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine sgp30Init
|
||||||
|
;
|
||||||
|
; Sends the given command to the sensor and reads the result.
|
||||||
|
; Synchronization is done by sending re-start sequences until the sensor answers with
|
||||||
|
; the value.
|
||||||
|
;
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @clobbers R14, R16 (R17, R18, R22)
|
||||||
|
|
||||||
|
sgp30Init:
|
||||||
|
; send request
|
||||||
|
ldi r20, HIGH(SGP30_CMD_INIT)
|
||||||
|
ldi r21, LOW(SGP30_CMD_INIT)
|
||||||
|
rcall sgp30SendCommand ; (R16, R20, R21, R17, R18, R22)
|
||||||
|
brcc sgp30Init_error
|
||||||
|
; no response expected, just STOP
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
sgp30Init_error:
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine sgp30Measure
|
||||||
|
;
|
||||||
|
; Sends the given command to the sensor and reads the result.
|
||||||
|
; Synchronization is done by sending re-start sequences until the sensor answers with
|
||||||
|
; the value.
|
||||||
|
;
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @return r19:r18 TVOC
|
||||||
|
; @return r21:r20 CO2 equivalent
|
||||||
|
; @clobbers R14, R16, R18, R19, R22
|
||||||
|
|
||||||
|
sgp30Measure:
|
||||||
|
ldi r20, HIGH(SGP30_CMD_MEASURE)
|
||||||
|
ldi r21, LOW(SGP30_CMD_MEASURE)
|
||||||
|
rcall sgp30SendCommand ; (R16, R20, R21, R17, R18, R22)
|
||||||
|
brcc sgp30Measure_error
|
||||||
|
|
||||||
|
; read response
|
||||||
|
rcall twiReceiveByteSendAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp30Measure_error
|
||||||
|
mov r21, r16 ; MSByte
|
||||||
|
rcall twiReceiveByteSendAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp30Measure_error
|
||||||
|
mov r20, r16 ; LSByte (CO2)
|
||||||
|
rcall twiReceiveByte ; R16=CRC8, no ACK (R16, R17, R18, R22)
|
||||||
|
brcc sgp30Measure_error
|
||||||
|
|
||||||
|
rcall twiReceiveByteSendAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp30Measure_error
|
||||||
|
mov r19, r16 ; MSByte
|
||||||
|
rcall twiReceiveByteSendAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp30Measure_error
|
||||||
|
mov r18, r16 ; LSByte
|
||||||
|
push r18
|
||||||
|
rcall twiReceiveByte ; R16=CRC8, no ACK (R16, R17, R18, R22)
|
||||||
|
pop r18
|
||||||
|
brcc sgp30Measure_error
|
||||||
|
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
sgp30Measure_error:
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine sgp30SendCommand
|
||||||
|
;
|
||||||
|
; Sends the given command to the sensor and reads the result.
|
||||||
|
; Synchronization is done by sending re-start sequences until the sensor answers with
|
||||||
|
; the value.
|
||||||
|
;
|
||||||
|
; @param R20 1st command byte
|
||||||
|
; @param R21 2nd command byte
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @clobbers R16, R20, R21 (R17, R18, R22)
|
||||||
|
|
||||||
|
sgp30SendCommand:
|
||||||
|
; send request
|
||||||
|
rcall twiStart ; (R22)
|
||||||
|
ldi r16, (SGP30_ADDR*2) ; write access
|
||||||
|
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp30SendCommand_error
|
||||||
|
mov r16, r20
|
||||||
|
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp30SendCommand_error
|
||||||
|
mov r16, r21
|
||||||
|
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp30SendCommand_error
|
||||||
|
|
||||||
|
; receive response
|
||||||
|
ldi r20, 15 ; wait max 15ms
|
||||||
|
sgp30SendCommand_loop1:
|
||||||
|
ldi r21, 10 ; 1ms
|
||||||
|
sgp30SendCommand_loop2: ; (R22)
|
||||||
|
rcall twiRestart
|
||||||
|
ldi r16, (SGP30_ADDR*2)+1 ; read access
|
||||||
|
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcs sgp30SendCommand_gotResponse ; chip responds, receive values
|
||||||
|
rcall Utils_WaitFor50MicroSecs ; wait for 100usecs total
|
||||||
|
rcall Utils_WaitFor50MicroSecs
|
||||||
|
dec r21
|
||||||
|
brne sgp30SendCommand_loop2
|
||||||
|
dec r20
|
||||||
|
brne sgp30SendCommand_loop1
|
||||||
|
rjmp sgp30SendCommand_error
|
||||||
|
sgp30SendCommand_gotResponse:
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
sgp30SendCommand_error:
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
43
avr/modules/sgp30/send.asm
Normal file
43
avr/modules/sgp30/send.asm
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
; ***************************************************************************
|
||||||
|
; 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. *
|
||||||
|
; ***************************************************************************
|
||||||
|
|
||||||
|
.cseg
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine SGP30_SendTVOC
|
||||||
|
|
||||||
|
SGP30_SendTVOC:
|
||||||
|
ldi r16, SGP30_VALUE_TVOC
|
||||||
|
rcall SGP30_GetValue
|
||||||
|
brcc SGP30_SendTVOC_end
|
||||||
|
ldi r17, VALUE_ID_TVOC ; VALUE ID
|
||||||
|
ldi r22, AQHOME_VALUETYPE_TVOC ; VALUE TYPE
|
||||||
|
rcall Main_SendValueReport
|
||||||
|
SGP30_SendTVOC_end:
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine SGP30_SendCO2
|
||||||
|
|
||||||
|
SGP30_SendCO2:
|
||||||
|
ldi r16, SGP30_VALUE_CO2
|
||||||
|
rcall SGP30_GetValue
|
||||||
|
brcc SGP30_SendCO2_end
|
||||||
|
ldi r17, VALUE_ID_CO2 ; VALUE ID
|
||||||
|
ldi r22, AQHOME_VALUETYPE_CO2 ; VALUE TYPE
|
||||||
|
rcall Main_SendValueReport
|
||||||
|
SGP30_SendCO2_end:
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
12
avr/modules/sgp40/0BUILD
Normal file
12
avr/modules/sgp40/0BUILD
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml?>
|
||||||
|
|
||||||
|
<gwbuild>
|
||||||
|
|
||||||
|
<extradist>
|
||||||
|
main.asm
|
||||||
|
send.asm
|
||||||
|
</extradist>
|
||||||
|
|
||||||
|
</gwbuild>
|
||||||
|
|
||||||
|
|
||||||
212
avr/modules/sgp40/main.asm
Normal file
212
avr/modules/sgp40/main.asm
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
; ***************************************************************************
|
||||||
|
; 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. *
|
||||||
|
; ***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ***************************************************************************
|
||||||
|
; defines
|
||||||
|
|
||||||
|
|
||||||
|
.equ SGP40_FLAGS_PRESENT_BIT = 7
|
||||||
|
.equ SGP40_FLAGS_DATAVALID_BIT = 6
|
||||||
|
|
||||||
|
.equ SGP40_CMD_MEASURE = 0x260f
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ***************************************************************************
|
||||||
|
; data
|
||||||
|
|
||||||
|
.dseg
|
||||||
|
|
||||||
|
sgp40DataBegin:
|
||||||
|
sgp40Flags: .byte 1
|
||||||
|
sgp40LastValue: .byte 2
|
||||||
|
sgp40DataEnd:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ***************************************************************************
|
||||||
|
; code
|
||||||
|
|
||||||
|
.cseg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; SGP40_Init
|
||||||
|
;
|
||||||
|
|
||||||
|
SGP40_Init:
|
||||||
|
ldi xh, HIGH(sgp40DataBegin)
|
||||||
|
ldi xl, LOW(sgp40DataBegin)
|
||||||
|
clr r16
|
||||||
|
ldi r17, (sgp40DataEnd-sgp40DataBegin)
|
||||||
|
rcall Utils_FillSram
|
||||||
|
|
||||||
|
; check presence
|
||||||
|
rcall sgp40CheckPresence
|
||||||
|
brcc SGP40_Init_error
|
||||||
|
lds r16, sgp40Flags
|
||||||
|
ori r16, (1<<SGP40_FLAGS_PRESENT_BIT)
|
||||||
|
sts sgp40Flags, r16
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
SGP40_Init_error:
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; SGP40_Fini
|
||||||
|
;
|
||||||
|
|
||||||
|
SGP40_Fini:
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine SGP40_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
|
||||||
|
|
||||||
|
SGP40_GetValue:
|
||||||
|
lds r16, sgp40Flags
|
||||||
|
andi r16, (1<<SGP40_FLAGS_DATAVALID_BIT)
|
||||||
|
brne SGP40_GetValue_gotValue
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
SGP40_GetValue_gotValue:
|
||||||
|
lds r18, sgp40LastValue
|
||||||
|
lds r19, sgp40LastValue+1
|
||||||
|
ldi r20, 1
|
||||||
|
clr r21
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine sgp40CheckPresence
|
||||||
|
;
|
||||||
|
; Expects interrupts being disabled!
|
||||||
|
;
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @clobbers R16 (R17, R18, R22)
|
||||||
|
|
||||||
|
sgp40CheckPresence:
|
||||||
|
ldi r16, (SGP40_ADDR*2)+1 ; read access
|
||||||
|
rjmp twiCheckPresence ; (R16, R17, R18, R22)
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SGP40_MeasureRawSignal:
|
||||||
|
in r15, SREG
|
||||||
|
push r15
|
||||||
|
cli
|
||||||
|
lds r17, sgp40Flags
|
||||||
|
sbrs r17, SGP40_FLAGS_PRESENT_BIT ; investigate PRESENT BIT
|
||||||
|
rjmp SGP40_MeasureRawSignal_error ; jmp if PRESENT bit clear
|
||||||
|
rcall sgp40Measure ; R19:18=value
|
||||||
|
brcc SGP40_MeasureRawSignal_error
|
||||||
|
lds r17, sgp40Flags
|
||||||
|
ori r17, (1<<SGP40_FLAGS_DATAVALID_BIT)
|
||||||
|
sts sgp40LastValue, r18
|
||||||
|
sts sgp40LastValue+1, r19
|
||||||
|
sts sgp40Flags, r17
|
||||||
|
SGP40_MeasureRawSignal_done:
|
||||||
|
pop r15
|
||||||
|
out SREG, r15
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
SGP40_MeasureRawSignal_error:
|
||||||
|
pop r15
|
||||||
|
out SREG, r15
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine sgp40Measure
|
||||||
|
;
|
||||||
|
; Sends the given command to the sensor and reads the result.
|
||||||
|
; Synchronization is done by sending re-start sequences until the sensor answers with
|
||||||
|
; the value.
|
||||||
|
;
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @return r19:r18 received raw value
|
||||||
|
; @clobbers R14, R16, R18, R19, R22
|
||||||
|
|
||||||
|
sgp40Measure:
|
||||||
|
; send request
|
||||||
|
rcall twiStart ; (R22)
|
||||||
|
ldi r16, (SGP40_ADDR*2) ; write access
|
||||||
|
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp40Measure_error
|
||||||
|
ldi zl, LOW(sgp40FlashDataCmdMeasureDefault*2)
|
||||||
|
ldi zh, HIGH(sgp40FlashDataCmdMeasureDefault*2)
|
||||||
|
ldi r19, 8
|
||||||
|
rcall twiSendFromFlashExpectAck
|
||||||
|
brcc sgp40Measure_error ; no ACK or other error
|
||||||
|
; receive response
|
||||||
|
ldi r16, 200
|
||||||
|
mov r14, r16
|
||||||
|
sgp40Measure_loop: ; (R22)
|
||||||
|
rcall twiRestart
|
||||||
|
ldi r16, (SGP40_ADDR*2)+1 ; read access
|
||||||
|
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcs sgp40Measure_gotValue ; chip responds, receive values
|
||||||
|
dec r14
|
||||||
|
breq sgp40Measure_error ; timeout
|
||||||
|
rcall Utils_WaitFor50MicroSecs ; wait for 100usecs total
|
||||||
|
rcall Utils_WaitFor50MicroSecs
|
||||||
|
rjmp sgp40Measure_loop
|
||||||
|
|
||||||
|
sgp40Measure_gotValue:
|
||||||
|
rcall twiReceiveByteSendAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp40Measure_error
|
||||||
|
mov r19, r16 ; MSByte
|
||||||
|
rcall twiReceiveByteSendAck ; (R16, R17, R18, R22)
|
||||||
|
brcc sgp40Measure_error
|
||||||
|
mov r18, r16 ; LSByte
|
||||||
|
push r18
|
||||||
|
rcall twiReceiveByte ; R16=CRC8, no ACK (R16, R17, R18, R22)
|
||||||
|
pop r18
|
||||||
|
brcc sgp40Measure_error
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
sgp40Measure_error:
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sgp40FlashDataCmdMeasureDefault: .db 0x26, 0x0f, 0x80, 0x00, 0xa2, 0x66, 0x66, 0x93
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
25
avr/modules/sgp40/send.asm
Normal file
25
avr/modules/sgp40/send.asm
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
; ***************************************************************************
|
||||||
|
; 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. *
|
||||||
|
; ***************************************************************************
|
||||||
|
|
||||||
|
.cseg
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine SGP40_SendTVOC
|
||||||
|
|
||||||
|
SGP40_SendTVOC:
|
||||||
|
rcall SGP40_GetValue
|
||||||
|
brcc SGP40_SendTVOC_end
|
||||||
|
ldi r17, VALUE_ID_TVOC ; VALUE ID
|
||||||
|
ldi r22, AQHOME_VALUETYPE_TVOC ; VALUE TYPE
|
||||||
|
rcall Main_SendValueReport
|
||||||
|
SGP40_SendTVOC_end:
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
@@ -168,18 +168,8 @@ SI7021_MeasureHumidity_error:
|
|||||||
; USED:
|
; USED:
|
||||||
|
|
||||||
si7021CheckPresence:
|
si7021CheckPresence:
|
||||||
rcall twiStart
|
|
||||||
ldi r16, (SI7021_ADDR*2)+1
|
ldi r16, (SI7021_ADDR*2)+1
|
||||||
rcall twiSendByte
|
rjmp twiCheckPresence
|
||||||
brcc si7021CheckPresence_notfound
|
|
||||||
rcall twiStop
|
|
||||||
sec
|
|
||||||
ret
|
|
||||||
|
|
||||||
si7021CheckPresence_notfound:
|
|
||||||
rcall twiStop
|
|
||||||
clc
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,30 @@ TWI_Master_Run:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine twiCheckPresence
|
||||||
|
;
|
||||||
|
; Expects interrupts being disabled!
|
||||||
|
;
|
||||||
|
; @param r16 address to check (with read bit set!)
|
||||||
|
; @return CFLAG set if okay, clear on error
|
||||||
|
; @clobbers (R16, R17, R18, R22)
|
||||||
|
|
||||||
|
twiCheckPresence:
|
||||||
|
rcall twiStart ; (R22)
|
||||||
|
rcall twiSendByte ; (R16, R17, R18, R22)
|
||||||
|
; rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcc twiCheckPresence_notfound
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
sec
|
||||||
|
ret
|
||||||
|
twiCheckPresence_notfound:
|
||||||
|
rcall twiStop ; (R22)
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; twiStart
|
; twiStart
|
||||||
@@ -257,6 +281,29 @@ twiWriteBit_clockReleased:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine twiSendFromFlashExpectAck
|
||||||
|
;
|
||||||
|
; Write bytes from flash to TWI expecting ACK bits.
|
||||||
|
;
|
||||||
|
; @param Z pointer to data in FLASH to send (prepared for "LPM"!)
|
||||||
|
; @param r19 number of bytes to send
|
||||||
|
; @return CFLAG set if okay, cleared on error
|
||||||
|
; @clobbers R16, R17, R18, R22, Z
|
||||||
|
|
||||||
|
twiSendFromFlashExpectAck:
|
||||||
|
twiSendFromFlashExpectAck_loop:
|
||||||
|
lpm r16, Z+
|
||||||
|
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||||
|
brcc twiSendFromFlashExpectAck_ret
|
||||||
|
dec r19
|
||||||
|
brne twiSendFromFlashExpectAck_loop
|
||||||
|
sec
|
||||||
|
twiSendFromFlashExpectAck_ret:
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; twiSendByte
|
; twiSendByte
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user