Browse Source

convert & print temperature, pressure, and humidity to USB serial

Enough to start hacking, adding features, and refining.
master
Daniel Peter Chokola 2 years ago
parent
commit
ef34698a00
  1. 55
      .cproject
  2. 2
      Core/Inc/main.h
  3. 24
      Core/Inc/terminal.h
  4. 46
      Core/Inc/util.h
  5. 2
      Core/Src/gpio.c
  6. 19
      Core/Src/main.c
  7. 2
      Core/Src/spi.c
  8. 136
      Core/Src/terminal.c
  9. 57
      Drivers/BME280/Inc/bme280.h
  10. 477
      Drivers/BME280/Src/bme280.c
  11. 11
      hothouse-mon.ioc

55
.cproject

@ -24,13 +24,17 @@
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.813197789" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.813197789" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.255620478" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.255620478" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.752622469" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F401CCUx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Drivers/CMSIS/Include | ../USB_DEVICE/App | ../USB_DEVICE/Target | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc || || || USE_HAL_DRIVER | STM32F401xC || || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE || || || ${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.752622469" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F401CCUx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Drivers/CMSIS/Include | ../USB_DEVICE/App | ../USB_DEVICE/Target | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc || || || USE_HAL_DRIVER | STM32F401xC || || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE || || || ${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.1376255223" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1998061963" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/> <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1998061963" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
<builder buildPath="${workspace_loc:/hothouse-mon}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.766542675" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/> <builder buildPath="${workspace_loc:/hothouse-mon}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.766542675" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.2104471420" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler"> <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.2104471420" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.1776738573" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g3" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.1776738573" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g3" valueType="enumerated"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols.1055126530" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols" valueType="definedSymbols"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols.1055126530" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="DEBUG"/> <listOptionValue builtIn="false" value="DEBUG"/>
</option> </option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths.515449045" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/BME280/Inc}&quot;"/>
</option>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.971296292" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/> <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.971296292" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
</tool> </tool>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1210937770" name="MCU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler"> <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1210937770" name="MCU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
@ -51,6 +55,7 @@
<listOptionValue builtIn="false" value="../USB_DEVICE/Target"/> <listOptionValue builtIn="false" value="../USB_DEVICE/Target"/>
<listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Core/Inc"/> <listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Core/Inc"/>
<listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc"/> <listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/BME280/Inc}&quot;"/>
</option> </option>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.746395805" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/> <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.746395805" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
</tool> </tool>
@ -59,7 +64,7 @@
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.1725010391" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.1725010391" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false"/>
</tool> </tool>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.431262741" name="MCU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker"> <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.431262741" name="MCU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script.70583072" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld}" valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script.70583072" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" useByScannerDiscovery="false" value="${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld}" valueType="string"/>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.302155928" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input"> <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.302155928" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
@ -102,27 +107,30 @@
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.377597308" name="Release" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release"> <configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.377597308" name="Release" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release">
<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.377597308." name="/" resourcePath=""> <folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.377597308." name="/" resourcePath="">
<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release.1752728520" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release"> <toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release.1752728520" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.1831914332" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32F401CCUx" valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.1831914332" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32F401CCUx" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.593719162" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.593719162" name="CPU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.1433799001" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.1433799001" name="Core" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.747355076" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.747355076" name="Floating-point unit" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.1125100677" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.1125100677" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1055393957" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1055393957" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.215791334" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F401CCUx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Drivers/CMSIS/Include | ../USB_DEVICE/App | ../USB_DEVICE/Target | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc || || || USE_HAL_DRIVER | STM32F401xC || || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE || || || ${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.215791334" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F401CCUx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Drivers/CMSIS/Include | ../USB_DEVICE/App | ../USB_DEVICE/Target | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc || || || USE_HAL_DRIVER | STM32F401xC || || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE || || || ${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.515036534" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/> <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.515036534" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
<builder buildPath="${workspace_loc:/hothouse-mon}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.663521244" managedBuildOn="true" name="Gnu Make Builder.Release" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/> <builder buildPath="${workspace_loc:/hothouse-mon}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.663521244" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.479285305" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler"> <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.479285305" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.1713256007" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g0" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.1713256007" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g0" valueType="enumerated"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths.457069664" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/BME280/Inc}&quot;"/>
</option>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.1006714338" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/> <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.1006714338" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
</tool> </tool>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.300030486" name="MCU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler"> <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.300030486" name="MCU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1252614775" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g0" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1252614775" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.919045125" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.os" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.919045125" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.os" valueType="enumerated"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.1840965707" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.1840965707" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/> <listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
<listOptionValue builtIn="false" value="STM32F401xC"/> <listOptionValue builtIn="false" value="STM32F401xC"/>
</option> </option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.328638015" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.328638015" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../Core/Inc"/> <listOptionValue builtIn="false" value="../Core/Inc"/>
<listOptionValue builtIn="false" value="../Drivers/STM32F4xx_HAL_Driver/Inc"/> <listOptionValue builtIn="false" value="../Drivers/STM32F4xx_HAL_Driver/Inc"/>
<listOptionValue builtIn="false" value="../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy"/> <listOptionValue builtIn="false" value="../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy"/>
@ -132,15 +140,16 @@
<listOptionValue builtIn="false" value="../USB_DEVICE/Target"/> <listOptionValue builtIn="false" value="../USB_DEVICE/Target"/>
<listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Core/Inc"/> <listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Core/Inc"/>
<listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc"/> <listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/BME280/Inc}&quot;"/>
</option> </option>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1074930983" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/> <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1074930983" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
</tool> </tool>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1201929364" name="MCU G++ Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler"> <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1201929364" name="MCU G++ Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.865649225" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.value.g0" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.865649225" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.357932916" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.value.os" valueType="enumerated"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.357932916" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.value.os" valueType="enumerated"/>
</tool> </tool>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.2012916395" name="MCU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker"> <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.2012916395" name="MCU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script.1037074767" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld}" valueType="string"/> <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script.1037074767" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="${workspace_loc:/${ProjName}/STM32F401CCUX_FLASH.ld}" valueType="string"/>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.993487305" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input"> <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.993487305" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
@ -183,4 +192,12 @@
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
</storageModule> </storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/hothouse-mon"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/hothouse-mon"/>
</configuration>
</storageModule>
</cproject> </cproject>

2
Core/Inc/main.h

@ -61,7 +61,7 @@ void Error_Handler(void);
#define SPI2_CS_GPIO_Port GPIOB #define SPI2_CS_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */ /* USER CODE BEGIN Private defines */
#define APP_NAME "hothouse"
/* USER CODE END Private defines */ /* USER CODE END Private defines */
#ifdef __cplusplus #ifdef __cplusplus

24
Core/Inc/terminal.h

@ -0,0 +1,24 @@
/*
* terminal.h
*
* Created on: Feb 26, 2023
* Author: Daniel Peter Chokola
*/
#ifndef TERMINAL_H_
#define TERMINAL_H_
/* Includes */
#include <stdint.h>
#include "usbd_cdc_if.h"
/* Definitions */
#define TERM_RXBUF_LEN (APP_RX_DATA_SIZE)
/* Function Prototypes */
void term_prompt();
void term_poll();
void term_rx(char *buf, uint32_t len);
void term_printf(const char *fmt, ...);
#endif /* TERMINAL_H_ */

46
Core/Inc/util.h

@ -0,0 +1,46 @@
/*
* util.h
*
* Created on: Feb 26, 2023
* Author: Daniel Peter Chokola
*/
#ifndef UTIL_H_
#define UTIL_H_
/* Definitions */
#define return_if_fail(cond) \
if(!(cond)) { return; }
#define return_val_if_fail(cond, val) \
if(!(cond)) { return (val); }
#define return_null_if_fail(cond) return_val_if_fail((cond), NULL)
/* MIN() and MAX() */
#ifdef __GNUC__
# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
/* prevent double evaluation */
# define MIN(a,b) \
__extension__({ __auto_type _a = (a); \
__auto_type _b = (b); \
_a < _b ? _a : _b; })
# define MAX(a,b) \
__extension__({ __auto_type _a = (a); \
__auto_type _b = (b); \
_a > _b ? _a : _b; })
# else
/* typesafety but double evaluation is possible */
# define MIN(a,b) \
__extension__({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
# define MAX(a,b) \
__extension__({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
# endif
#else
/* no typesafety and double evaluation is possible */
# define MIN(a,b) ((a) < (b) ? (a) : (b))
# define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#endif /* UTIL_H_ */

2
Core/Src/gpio.c

@ -51,7 +51,7 @@ void MX_GPIO_Init(void)
__HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */ /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : PtPin */ /*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = SPI2_CS_Pin; GPIO_InitStruct.Pin = SPI2_CS_Pin;

19
Core/Src/main.c

@ -24,7 +24,9 @@
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
#include "bme280.h"
#include "terminal.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
@ -65,7 +67,7 @@ void SystemClock_Config(void);
int main(void) int main(void)
{ {
/* USER CODE BEGIN 1 */ /* USER CODE BEGIN 1 */
bme280_t bme280;
/* USER CODE END 1 */ /* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/ /* MCU Configuration--------------------------------------------------------*/
@ -89,17 +91,22 @@ int main(void)
MX_SPI2_Init(); MX_SPI2_Init();
MX_USB_DEVICE_Init(); MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
bme280_init(&bme280, &hspi2, SPI2_CS_GPIO_Port, SPI2_CS_Pin);
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Infinite loop */ /* Infinite loop */
/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */
while (1) while(1)
{ {
term_printf("T: %f DegC, P: %f hPa, H: %f %%RH\r\n",
(double) bme280_temp_get(&bme280) / 100.0,
(double) bme280_press_get(&bme280) / 25600.0,
(double) bme280_hum_get(&bme280) / 1024.0);
HAL_Delay(1000);
}
/* USER CODE END WHILE */ /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */ /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */ /* USER CODE END 3 */
} }

2
Core/Src/spi.c

@ -44,7 +44,7 @@ void MX_SPI2_Init(void)
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

136
Core/Src/terminal.c

@ -0,0 +1,136 @@
/*
* terminal.c
*
* Created on: Aug 2, 2022
* Author: daniel.chokola
*/
/* Includes */
#include <string.h>
#include <stdarg.h>
/*
#include "config.h"
*/
#include "terminal.h"
/* Private Variables */
static char wbuf[TERM_RXBUF_LEN]; /* working buffer */
static char rxbuf[TERM_RXBUF_LEN]; /* receive buffer */
static uint32_t rxlen;
static int8_t rxline;
/* Function Prototypes */
__attribute__((always_inline)) inline int8_t term_is_whitespace(char c)
{
if(c == '\n' ||
c == '\r' ||
c == '\t' ||
c == '\v' ||
c == '\f' ||
c == ' ')
{
return !0;
}
return 0;
}
static int32_t term_stripn(char *buf, int32_t n);
/* Function Definitions */
void term_prompt()
{
/*
term_printf("\r%s-g%s $ ", APP_NAME, GIT_REV);
*/
term_printf("\r%s $ ", APP_NAME);
}
void term_rx(char *buf, uint32_t len)
{
uint32_t i;
char c;
for(i = 0; i < len; i++)
{
c = buf[i];
/* ignore null bytes */
if(c == '\0')
{
continue;
}
/* handle backspace */
if(c == '\b')
{
if(rxlen)
{
rxlen--;
}
rxbuf[rxlen] = '\0';
if(rxlen)
{
/* term_printf("\b\x1b[0K"); */
}
continue;
}
/* handle escape sequences */
if(c == '\x1b')
{
c = '^';
}
rxbuf[rxlen++] = (char) c;
/* local echo */
/* term_printf("%c", c); */
if(c == '\n' || c == '\r')
{
/* EOL */
rxbuf[rxlen - 1] = '\0';
rxline = 1;
}
}
}
void term_printf(const char *fmt, ...)
{
va_list args;
int32_t len;
uint8_t res;
va_start(args, fmt);
len = vsprintf(wbuf, fmt, args);
va_end(args);
/* FIXME: this will lock up if there's too much Tx/Rx traffic */
do
{
res = CDC_Transmit_FS((uint8_t *) wbuf, (uint16_t) len);
}
while(res == USBD_BUSY);
}
/* strip trailing whitespace from a string of length n */
static int32_t term_stripn(char *buf, int32_t n)
{
int32_t i = n - 1;
while(i >= 0)
{
if(term_is_whitespace(buf[i]))
{
buf[i--] = '\0';
}
else if(buf[i] == '\0')
{
i--;
continue;
}
else
{
break;
}
}
return i + 1;
}

57
Drivers/BME280/Inc/bme280.h

@ -0,0 +1,57 @@
/*
* bme280.h
*
* Created on: Feb 26, 2023
* Author: Daniel Peter Chokola
* License: Beerware - Use this code however you'd like. If you find it
* useful you can buy me a beer some time.
*/
#ifndef BME280_H_
#define BME280_H_
/* Includes */
#include <stdint.h>
#include "spi.h"
/* Definitions */
#define BME280_CAL_LEN (32u)
/* Data Structures */
typedef struct bme280_s {
SPI_HandleTypeDef *hspi;
GPIO_TypeDef *port;
uint16_t pin;
union __attribute__((packed, aligned(1))) bme280_calib_u {
uint8_t byte[BME280_CAL_LEN];
struct __attribute__((packed, aligned(1))) bme280_calib_s {
uint16_t cal_t1;
int16_t cal_t2;
int16_t cal_t3;
uint16_t cal_p1;
int16_t cal_p2;
int16_t cal_p3;
int16_t cal_p4;
int16_t cal_p5;
int16_t cal_p6;
int16_t cal_p7;
int16_t cal_p8;
int16_t cal_p9;
uint8_t cal_h1;
int16_t cal_h2;
uint8_t cal_h3;
int16_t cal_h4;
int16_t cal_h5;
int8_t cal_h6;
} field;
} cal;
int32_t t_fine;
} bme280_t;
/* Function Prototypes */
int32_t bme280_init(bme280_t *bme280, SPI_HandleTypeDef *hspi, GPIO_TypeDef *port, uint16_t pin);
int32_t bme280_temp_get(bme280_t *bme280);
int32_t bme280_press_get(bme280_t *bme280);
int32_t bme280_hum_get(bme280_t *bme280);
#endif /* BME280_H_ */

477
Drivers/BME280/Src/bme280.c

@ -0,0 +1,477 @@
/*
* bme280.c
*
* Created on: Feb 26, 2023
* Author: Daniel Peter Chokola
* License: Beerware - Use this code however you'd like. If you find it
* useful you can buy me a beer some time.
*/
/* Includes */
#include "bme280.h"
#include "spi.h"
#include "util.h"
/* Definitions */
/* BME280 registers */
#define BME280_REG_HUM_LSB (0xfe)
#define BME280_REG_HUM_MSB (0xfd)
#define BME280_REG_TEMP_XLSB (0xfc)
#define BME280_REG_TEMP_LSB (0xfb)
#define BME280_REG_TEMP_MSB (0xfa)
#define BME280_REG_PRESS_XLSB (0xf9)
#define BME280_REG_PRESS_LSB (0xf8)
#define BME280_REG_PRESS_MSB (0xf7)
#define BME280_REG_CONFIG (0xf5)
#define BME280_REG_CTRL_MEAS (0xf4)
#define BME280_REG_STATUS (0xf3)
#define BME280_REG_CTRL_HUM (0xf2)
#define BME280_REG_RESET (0xe0)
#define BME280_REG_ID (0xd0) /* should return 0x60 when read (BME280) */
#define BME280_REG_CALIB26 (0xe1)
#define BME280_REG_CALIB25 (0xa1)
#define BME280_REG_CALIB00 (0x88)
/* BME280 SPI Register Masks */
#define BME280_READ_MASK (0x80)
#define BME280_WRITE_MASK (0x7f)
/* BME280 Magic Register Values */
#define BME280_RESET (0xb6)
#define BME280_ID (0x60)
#define BMP280_ID_PROD (0x58)
#define BMP280_ID_SAMP1 (0x56)
#define BMP280_ID_SAMP2 (0x57)
enum H_OSR {
H_OSR_00 = 0, /* skip */
H_OSR_01,
H_OSR_02,
H_OSR_04,
H_OSR_08,
H_OSR_16
};
enum P_OSR {
P_OSR_00 = 0, /* skip */
P_OSR_01,
P_OSR_02,
P_OSR_04,
P_OSR_08,
P_OSR_16
};
enum T_OSR {
T_OSR_00 = 0, /* skip */
T_OSR_01,
T_OSR_02,
T_OSR_04,
T_OSR_08,
T_OSR_16
};
enum IIR_COEFF {
IIR_OFF = 0, /* no filtering */
IIR_02,
IIR_04,
IIR_08,
IIR_16,
};
enum MODE {
MODE_SLEEP = 0,
MODE_FORCED1,
MODE_FORCED2,
MODE_NORMAL
};
enum STBY_TIME {
STBY_00_5ms = 0,
STBY_62_5ms,
STBY_125ms,
STBY_250ms,
STBY_500ms,
STBY_1000ms,
STBY_10ms, /* 2000 ms on BMP280 */
STBY_20ms, /* 4000 ms on BMP280 */
};
/* Data Structures */
/* Function Prototypes */
static int32_t bme280_cal_get(bme280_t *bme280);
static int32_t bme280_writebyte(bme280_t *bme280, uint8_t reg, uint8_t byte);
static int32_t bme280_readbyte(bme280_t *bme280, uint8_t reg, uint8_t *byte);
static int32_t bme280_compensate_t(bme280_t *bme280, int32_t t);
static uint32_t bme280_compensate_p(bme280_t *bme280, int32_t p_comp);
static uint32_t bme280_compensate_h(bme280_t *bme280, int32_t h);
/* Function Definitions */
int32_t bme280_init(bme280_t *bme280, SPI_HandleTypeDef *hspi, GPIO_TypeDef *port, uint16_t pin)
{
uint8_t id = 0;
return_val_if_fail(bme280, -1);
return_val_if_fail(hspi, -1);
bme280->hspi = hspi;
bme280->port = port;
bme280->pin = pin;
/*
* toggle CS line and send a dummy byte to to put the chip in SPI mode and
* let the SPI lines settle */
return_val_if_fail(bme280_writebyte(bme280, BME280_REG_RESET, 0x00) == 0, -1);
/* reset */
return_val_if_fail(bme280_writebyte(bme280, BME280_REG_RESET, BME280_RESET) == 0, -1);
HAL_Delay(1); /* give the chip a millisecond to come out of reset */
/* query chip ID */
return_val_if_fail(bme280_readbyte(bme280, BME280_REG_ID, &id) == 0, -1);
switch(id)
{
case BME280_ID:
/* BME280 */
break;
case BMP280_ID_PROD:
case BMP280_ID_SAMP1:
case BMP280_ID_SAMP2:
/* maybe support these one day */
default:
return -1; /* not a BME280 */
}
/* fetch calibration constants */
return_val_if_fail(bme280_cal_get(bme280) == 0, -1);
/*
* FIXME: don't hardcode these
* Maybe leave the chip in sleep mode here and create new function(s) to
* adjust config?
*/
/* configure humidity acquisition options */
return_val_if_fail(bme280_writebyte(bme280, BME280_REG_CTRL_HUM, H_OSR_01) == 0, -1);
/* configure temperature and pressure acquisition options and acquisition mode */
return_val_if_fail(bme280_writebyte(bme280,
BME280_REG_CTRL_MEAS,
(T_OSR_01 << 5) | (P_OSR_16 << 2) | MODE_NORMAL) == 0,
-1);
/* configure acquisition rate, IIR filtering, and SPI options */
return_val_if_fail(bme280_writebyte(bme280,
BME280_REG_CONFIG,
(STBY_00_5ms << 5) | (IIR_16 << 2) | 0) == 0,
-1);
return 0;
}
int32_t bme280_temp_get(bme280_t *bme280)
{
uint8_t reg;
uint8_t rxdata[3];
int32_t t;
HAL_StatusTypeDef res;
/* read temperature; data must be read in one transaction to guarantee consistency */
reg = BME280_REG_TEMP_MSB;
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_Transmit(bme280->hspi, &reg, 1, 10);
res |= HAL_SPI_Receive(bme280->hspi, &(rxdata[0]), 3, 10);
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
/* assemble raw temperature */
t = ((int32_t) rxdata[0] << 12) | ((uint32_t) rxdata[1] << 4) | ((uint32_t) rxdata[2] >> 4);
return bme280_compensate_t(bme280, t);
}
int32_t bme280_press_get(bme280_t *bme280)
{
uint8_t reg;
uint8_t rxdata[3];
int32_t p;
HAL_StatusTypeDef res;
/* read pressure; data must be read in one transaction to guarantee consistency */
reg = BME280_REG_PRESS_MSB;
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_Transmit(bme280->hspi, &reg, 1, 10);
res |= HAL_SPI_Receive(bme280->hspi, &(rxdata[0]), 3, 10);
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
/* assemble raw temperature */
p = ((int32_t) rxdata[0] << 12) | ((uint32_t) rxdata[1] << 4) | ((uint32_t) rxdata[2] >> 4);
return bme280_compensate_p(bme280, p);
}
int32_t bme280_hum_get(bme280_t *bme280)
{
uint8_t reg;
uint8_t rxdata[2];
int32_t h;
HAL_StatusTypeDef res;
/* read pressure; data must be read in one transaction to guarantee consistency */
reg = BME280_REG_HUM_MSB;
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_Transmit(bme280->hspi, &reg, 1, 10);
res |= HAL_SPI_Receive(bme280->hspi, &(rxdata[0]), 2, 10);
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
/* assemble raw temperature */
h = ((int32_t) rxdata[0] << 8) | rxdata[1];
return bme280_compensate_h(bme280, h);
}
static int32_t bme280_cal_get(bme280_t *bme280)
{
uint8_t reg;
uint8_t calh[7]; /* humidity cal which needs some massaging */
int32_t i;
HAL_StatusTypeDef res;
for(i = 0; i < BME280_CAL_LEN; i++)
{
bme280->cal.byte[i] = 0;
}
reg = BME280_REG_CALIB00;
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_Transmit(bme280->hspi, &reg, 1, 10);
res |= HAL_SPI_Receive(bme280->hspi, &(bme280->cal.byte[ 0]), 24, 10);
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
reg = BME280_REG_CALIB25;
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_Transmit(bme280->hspi, &reg, 1, 10);
res |= HAL_SPI_Receive(bme280->hspi, &(bme280->cal.byte[24]), 1, 10);
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
reg = BME280_REG_CALIB26;
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_Transmit(bme280->hspi, &reg, 1, 10);
res |= HAL_SPI_Receive(bme280->hspi, &(calh[0]), 7, 10);
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
/* massage the humidity cal into its struct */
bme280->cal.field.cal_h2 = ((int16_t) calh[1] << 8) | calh[0];
bme280->cal.field.cal_h3 = calh[2];
bme280->cal.field.cal_h4 = ((int16_t) calh[3] << 4) | (calh[4] & 0x0f);
bme280->cal.field.cal_h5 = ((int16_t) calh[5] << 4) | ((calh[4] >> 4) & 0x0f);
bme280->cal.field.cal_h6 = (int8_t) calh[6];
return 0;
}
static int32_t bme280_writebyte(bme280_t *bme280, uint8_t reg, uint8_t byte)
{
uint8_t txdata[2] = { reg & BME280_WRITE_MASK, byte };
HAL_StatusTypeDef res;
/* assert chip select */
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_Transmit(bme280->hspi, &(txdata[0]), 2, 10);
/* deassert chip select */
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
return 0;
}
static int32_t bme280_readbyte(bme280_t *bme280, uint8_t reg, uint8_t *byte)
{
uint8_t txdata[2] = { reg | BME280_READ_MASK, 0x00 };
uint8_t rxdata[2];
HAL_StatusTypeDef res;
/* assert chip select */
bme280->port->BSRR = bme280->pin << 16;
res = HAL_SPI_TransmitReceive(bme280->hspi, &(txdata[0]), &(rxdata[0]), 2, 10);
/* deassert chip select */
bme280->port->BSRR = bme280->pin;
return_val_if_fail(res == HAL_OK, -1);
*byte = rxdata[1];
return 0;
}
/*
* Returns temperature in DegC, resolution is 0.01 DegC. Output value of
* "5123" equals 51.23 DegC.
*/
static int32_t bme280_compensate_t(bme280_t *bme280, int32_t t)
{
int32_t var1;
int32_t var2;
int32_t t_comp;
var1 = ((((t >> 3) - ((int32_t) bme280->cal.field.cal_t1 << 1))) * ((int32_t) bme280->cal.field.cal_t2)) >> 11;
var2 = (((((t >> 4) - ((int32_t) bme280->cal.field.cal_t1)) * ((t >> 4) - ((int32_t) bme280->cal.field.cal_t1))) >> 12) * ((int32_t) bme280->cal.field.cal_t3)) >> 14;
bme280->t_fine = var1 + var2;
t_comp = (bme280->t_fine * 5 + 128) >> 8;
return t_comp;
}
/*
* Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24
* integer bits and 8 fractional bits).
* Output value of "24674867" represents 24674867/256 = 96386.2 Pa =
* 963.862 hPa
*/
static uint32_t bme280_compensate_p(bme280_t *bme280, int32_t p)
{
int64_t var1;
int64_t var2;
int64_t p_comp;
var1 = ((int64_t) bme280->t_fine) - 128000;
var2 = var1 * var1 * (int64_t) bme280->cal.field.cal_p6;
var2 = var2 + ((var1 * (int64_t) bme280->cal.field.cal_p5) << 17);
var2 = var2 + (((int64_t) bme280->cal.field.cal_p4) << 35);
var1 = ((var1 * var1 * (int64_t) bme280->cal.field.cal_p3) >> 8) + ((var1 * (int64_t) bme280->cal.field.cal_p2) << 12);
var1 = (((((int64_t) 1) << 47) + var1)) * ((int64_t) bme280->cal.field.cal_p1) >> 33;
if(var1 == 0)
{
/* division by zero */
return 0;
}
p_comp = 1048576 - p;
p_comp = (((p_comp << 31) - var2) * 3125) / var1;
var1 = (((int64_t) bme280->cal.field.cal_p9) * (p_comp >> 13) * (p_comp >> 13)) >> 25;
var2 = (((int64_t) bme280->cal.field.cal_p8) * p_comp) >> 19;
p_comp = ((p_comp + var1 + var2) >> 8) + (((int64_t) bme280->cal.field.cal_p7) << 4);
return (uint32_t) p_comp;
}
/*
* Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22
* integer and 10 fractional bits).
* Output value of 47445 represents 47445/1024 = 46.333 %RH
*/
static uint32_t bme280_compensate_h(bme280_t *bme280, int32_t h)
{
int32_t h_comp;
h_comp = (bme280->t_fine - ((int32_t) 76800));
h_comp = (((((h << 14) - (((int32_t) bme280->cal.field.cal_h4) << 20) - (((int32_t) bme280->cal.field.cal_h5) *
h_comp)) + ((int32_t) 16384)) >> 15) * (((((((h_comp *
((int32_t) bme280->cal.field.cal_h6)) >> 10) * (((h_comp * ((int32_t) bme280->cal.field.cal_h3)) >> 11) +
((int32_t) 32768))) >> 10) + ((int32_t) 2097152)) * ((int32_t) bme280->cal.field.cal_h2) +
8192) >> 14));
h_comp = (h_comp - (((((h_comp >> 15) * (h_comp >> 15)) >> 7) *
((int32_t) bme280->cal.field.cal_h1)) >> 4));
h_comp = (h_comp < 0 ? 0 : h_comp);
h_comp = (h_comp > 419430400 ? 419430400 : h_comp);
return (uint32_t) (h_comp >> 12);
}
#if (0) /* crusty old code */
/* Global Variables */
/* Specify BME280 configuration */
uint8_t Posr = P_OSR_16;
uint8_t Tosr = T_OSR_02;
uint8_t Mode = normal;
uint8_t IIRFilter = BW0_042ODR;
uint8_t SBy = t_62_5ms; // set pressure and temperature output data rate
/* t_fine carries fine temperature as global value for BME280 */
int32_t t_fine;
/* BME280 compensation parameters */
uint16_t dig_T1, dig_P1;
int16_t dig_T2, dig_T3, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
double Temperature, Pressure; // stores BME280 pressures sensor pressure and temperature
int32_t rawPress, rawTemp; // pressure and temperature raw count output for BME280
/* Function Definitions */
int32_t readBME280Temperature()
{
uint8_t rawData[3]; // 20-bit pressure register data stored here
HAL_I2C_Mem_Read(&hi2c1, BME280_ADDRESS, BME280_TEMP_MSB, 3, &rawData[0], 3, 10);
return (int32_t) (((int32_t) rawData[0] << 16 | (int32_t) rawData[1] << 8 | rawData[2]) >> 4);
}
int32_t readBME280Pressure()
{
uint8_t rawData[3]; // 20-bit pressure register data stored here
HAL_I2C_Mem_Read(&hi2c1, BME280_ADDRESS, BME280_PRESS_MSB, 3, &rawData[0], 3, 10);
return (int32_t) (((int32_t) rawData[0] << 16 | (int32_t) rawData[1] << 8 | rawData[2]) >> 4);
}
void BME280Init()
{
uint8_t TPosrMode = Tosr << 5 | Posr << 2 | Mode;
uint8_t SByTimeIntervalModeAndBandwidth = SBy << 5 | IIRFilter << 2;
uint8_t calib[24];
/* Configure the BME280 */
/* Set T and P oversampling rates and sensor mode */
HAL_I2C_Mem_Write(&hi2c1, BME280_ADDRESS, BME280_CTRL_MEAS, 1, &TPosrMode, 1, 10);
/* Set standby time interval in normal mode and bandwidth */
HAL_I2C_Mem_Write(&hi2c1, BME280_ADDRESS, BME280_CONFIG, 1, &SByTimeIntervalModeAndBandwidth, 1, 10);
/* Read and store calibration data */
HAL_I2C_Mem_Read(&hi2c1, BME280_ADDRESS, BME280_CALIB00, 24, &calib[0], 24, 10);
dig_T1 = (uint16_t) (((uint16_t) calib[ 1] << 8) | calib[ 0]);
dig_T2 = ( int16_t) ((( int16_t) calib[ 3] << 8) | calib[ 2]);
dig_T3 = ( int16_t) ((( int16_t) calib[ 5] << 8) | calib[ 4]);
dig_P1 = (uint16_t) (((uint16_t) calib[ 7] << 8) | calib[ 6]);
dig_P2 = ( int16_t) ((( int16_t) calib[ 9] << 8) | calib[ 8]);
dig_P3 = ( int16_t) ((( int16_t) calib[11] << 8) | calib[10]);
dig_P4 = ( int16_t) ((( int16_t) calib[13] << 8) | calib[12]);
dig_P5 = ( int16_t) ((( int16_t) calib[15] << 8) | calib[14]);
dig_P6 = ( int16_t) ((( int16_t) calib[17] << 8) | calib[16]);
dig_P7 = ( int16_t) ((( int16_t) calib[19] << 8) | calib[18]);
dig_P8 = ( int16_t) ((( int16_t) calib[21] << 8) | calib[20]);
dig_P9 = ( int16_t) ((( int16_t) calib[23] << 8) | calib[22]);
}
/*
* Returns temperature in DegC, resolution is 0.01 DegC. Output value of
* "5123" equals 51.23 DegC.
*/
int32_t bmp280_compensate_T(int32_t adc_T)
{
int32_t var1, var2, T;
var1 = ((((adc_T >> 3) - ((int32_t) dig_T1 << 1))) * ((int32_t) dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t) dig_T1)) * ((adc_T >> 4) - ((int32_t) dig_T1))) >> 12) * ((int32_t) dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
/*
* Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24
* integer bits and 8 fractional bits).
* Output value of "24674867" represents 24674867/256 = 96386.2 Pa =
* 963.862 hPa
*/
uint32_t bmp280_compensate_P(int32_t adc_P)
{
uint64_t var1, var2, p;
var1 = ((uint64_t) t_fine) - 128000;
var2 = var1 * var1 * (uint64_t) dig_P6;
var2 = var2 + ((var1 * (uint64_t) dig_P5) << 17);
var2 = var2 + (((uint64_t) dig_P4) << 35);
var1 = ((var1 * var1 * (uint64_t) dig_P3) >> 8) + ((var1 * (uint64_t) dig_P2) << 12);
var1 = (((((uint64_t) 1) << 47) + var1)) * ((uint64_t) dig_P1) >> 33;
if(var1 == 0)
{
/* division by zero */
return 0;
}
p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = (((uint64_t) dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((uint64_t) dig_P8) * p)>> 19;
p = ((p + var1 + var2) >> 8) + (((uint64_t) dig_P7) << 4);
return (uint32_t) p;
}
#endif /* crusty old code */

11
hothouse-mon.ioc

@ -55,9 +55,11 @@ PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK PA14.Signal=SYS_JTCK-SWCLK
PB12.GPIOParameters=GPIO_Label PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PB12.GPIO_Label=SPI2_CS PB12.GPIO_Label=SPI2_CS
PB12.GPIO_Speed=GPIO_SPEED_FREQ_LOW
PB12.Locked=true PB12.Locked=true
PB12.PinState=GPIO_PIN_SET
PB12.Signal=GPIO_Output PB12.Signal=GPIO_Output
PB13.Locked=true PB13.Locked=true
PB13.Mode=Full_Duplex_Master PB13.Mode=Full_Duplex_Master
@ -102,7 +104,7 @@ ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=STM32CubeIDE ProjectManager.TargetToolchain=STM32CubeIDE
ProjectManager.ToolChainLocation= ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=true ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_SPI2_Init-SPI2-false-HAL-true,4-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false
RCC.48MHZClocksFreq_Value=48000000 RCC.48MHZClocksFreq_Value=48000000
RCC.AHBFreq_Value=72000000 RCC.AHBFreq_Value=72000000
RCC.APB1CLKDivider=RCC_HCLK_DIV2 RCC.APB1CLKDivider=RCC_HCLK_DIV2
@ -131,9 +133,10 @@ RCC.VCOI2SOutputFreq_Value=192000000
RCC.VCOInputFreq_Value=1000000 RCC.VCOInputFreq_Value=1000000
RCC.VCOOutputFreq_Value=144000000 RCC.VCOOutputFreq_Value=144000000
RCC.VcooutputI2S=96000000 RCC.VcooutputI2S=96000000
SPI2.CalculateBaudRate=18.0 MBits/s SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4
SPI2.CalculateBaudRate=9.0 MBits/s
SPI2.Direction=SPI_DIRECTION_2LINES SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
SPI2.Mode=SPI_MODE_MASTER SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER SPI2.VirtualType=VM_MASTER
USB_DEVICE.CLASS_NAME_FS=CDC USB_DEVICE.CLASS_NAME_FS=CDC

Loading…
Cancel
Save