凌云物联网实验室ISKBoard(IoT Starter Kits Board)开发板项目源码
guowenxue
2023-04-03 32806da6f5647ac637fa7d48aa9c221b091ab35e
Add ISKBoard_QCTester project
60 files added
10359 ■■■■■ changed files
Production/ISKBoard_QCTester/.cproject 182 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/.mxproject 37 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/.project 32 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs 2 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/.settings/language.settings.xml 25 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/.settings/org.eclipse.cdt.core.prefs 6 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/.settings/stm32cubeide.project.prefs 4 ●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/comport.c 238 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/comport.h 45 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/ds18b20.c 237 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/ds18b20.h 13 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/font_oled.h 205 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/hal_oled.c 280 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/hal_oled.h 45 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/i2c_bitbang.c 354 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/i2c_bitbang.h 84 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/isl1208.c 329 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/isl1208.h 37 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/miscdev.c 172 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/miscdev.h 80 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/ringbuf.c 109 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/ringbuf.h 58 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/sht20.c 211 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/sht20.h 19 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/w25q32.c 1025 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/w25q32.h 60 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/ws2812b.c 169 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Board/ws2812b.h 48 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/ESP/at-esp32.c 382 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/ESP/at-esp32.h 137 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/ESP/atcmd.c 287 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/ESP/atcmd.h 88 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/ESP/esp32.c 198 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/ESP/esp32.h 32 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/ESP/logger.h 31 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/adc.h 52 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/can.h 62 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/gpio.h 49 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/main.h 116 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/spi.h 52 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/stm32l4xx_hal_conf.h 482 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/stm32l4xx_it.h 72 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/tim.h 57 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Inc/usart.h 61 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/adc.c 163 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/can.c 293 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/gpio.c 130 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/main.c 703 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/spi.c 121 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/stm32l4xx_hal_msp.c 81 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/stm32l4xx_it.c 293 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/syscalls.c 176 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/sysmem.c 79 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/system_stm32l4xx.c 332 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/tim.c 221 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Src/usart.c 409 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/Core/Startup/startup_stm32l431rctx.s 461 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/ISKBoard_QCTester Debug.launch 79 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/ISKBoard_QCTester.ioc 367 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/STM32L431RCTX_FLASH.ld 187 ●●●●● patch | view | raw | blame | history
Production/ISKBoard_QCTester/.cproject
New file
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
    <storageModule moduleId="org.eclipse.cdt.core.settings">
        <cconfiguration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984">
            <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984" moduleId="org.eclipse.cdt.core.settings" name="Debug">
                <externalSettings/>
                <extensions>
                    <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
                    <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                </extensions>
            </storageModule>
            <storageModule moduleId="cdtBuildSystem" version="4.0.0">
                <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.debug" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984" name="Debug" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug">
                    <folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984." name="/" resourcePath="">
                        <toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug.369660556" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug">
                            <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.2103933359" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32L431RCTx" valueType="string"/>
                            <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.1757044456" 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.324008652" 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.1278791425" 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.1485422730" 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.421993750" 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.1564597215" 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.6 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32L431RCTx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32L4xx_HAL_Driver/Inc | ../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32L4xx/Include | ../Drivers/CMSIS/Include ||  ||  || USE_HAL_DRIVER | STM32L431xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32L431RCTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None ||  ||  || " valueType="string"/>
                            <option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.728278903" name="Cpu clock frequence" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="80" valueType="string"/>
                            <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.602987071" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
                            <builder buildPath="${workspace_loc:/ISKBoard_BareMetal}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.206690691" 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.1852606975" 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.878201567" 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 IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols.1112296306" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols" valueType="definedSymbols">
                                    <listOptionValue builtIn="false" value="DEBUG"/>
                                </option>
                                <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.231010816" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
                            </tool>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.859911740" 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.189626527" 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.g3" valueType="enumerated"/>
                                <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.1740229019" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false"/>
                                <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.1707283178" 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="DEBUG"/>
                                    <listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
                                    <listOptionValue builtIn="false" value="STM32L431xx"/>
                                </option>
                                <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.657546956" 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/ESP"/>
                                    <listOptionValue builtIn="false" value="../Core/Board"/>
                                    <listOptionValue builtIn="false" value="../Drivers/STM32L4xx_HAL_Driver/Inc"/>
                                    <listOptionValue builtIn="false" value="../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy"/>
                                    <listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32L4xx/Include"/>
                                    <listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
                                </option>
                                <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1387344889" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
                            </tool>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1111584846" 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.882978263" 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.g3" valueType="enumerated"/>
                                <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.2038536387" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false"/>
                            </tool>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.1128790366" 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.1550603345" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="${workspace_loc:/${ProjName}/STM32L431RCTX_FLASH.ld}" valueType="string"/>
                                <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags.1903274547" name="Other flags" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags" useByScannerDiscovery="false" valueType="stringList">
                                    <listOptionValue builtIn="false" value="-u _printf_float"/>
                                </option>
                                <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.1436834246" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
                                    <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
                                    <additionalInput kind="additionalinput" paths="$(LIBS)"/>
                                </inputType>
                            </tool>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.704802323" name="MCU G++ Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver.193635021" name="MCU GCC Archiver" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size.1827847333" name="MCU Size" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile.1443246891" name="MCU Output Converter list file" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex.226431864" name="MCU Output Converter Hex" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary.1482121916" name="MCU Output Converter Binary" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog.1375124649" name="MCU Output Converter Verilog" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec.1439333328" name="MCU Output Converter Motorola S-rec" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec.747940564" name="MCU Output Converter Motorola S-rec with symbols" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec"/>
                        </toolChain>
                    </folderInfo>
                    <sourceEntries>
                        <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
                        <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
                    </sourceEntries>
                </configuration>
            </storageModule>
            <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
        </cconfiguration>
        <cconfiguration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.602940913">
            <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.602940913" moduleId="org.eclipse.cdt.core.settings" name="Release">
                <externalSettings/>
                <extensions>
                    <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
                    <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
                    <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
                </extensions>
            </storageModule>
            <storageModule moduleId="cdtBuildSystem" version="4.0.0">
                <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.602940913" 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.602940913." name="/" resourcePath="">
                        <toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release.1761512170" 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.1475982704" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32L431RCTx" valueType="string"/>
                            <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.1546642591" 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.259727423" 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.95383444" 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.849128184" 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.34757845" 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.742851534" 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.6 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32L431RCTx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32L4xx_HAL_Driver/Inc | ../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32L4xx/Include | ../Drivers/CMSIS/Include ||  ||  || USE_HAL_DRIVER | STM32L431xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32L431RCTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None ||  ||  || " valueType="string"/>
                            <option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.1053420611" name="Cpu clock frequence" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="80" valueType="string"/>
                            <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.733976577" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
                            <builder buildPath="${workspace_loc:/ISKBoard_BareMetal}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.2046493537" 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.2146717068" 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.1445316476" 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"/>
                                <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.1128139411" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
                            </tool>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.342548357" 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.121420081" 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.1146109265" 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.995295969" 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="STM32L431xx"/>
                                </option>
                                <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.1392002630" 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="../Drivers/STM32L4xx_HAL_Driver/Inc"/>
                                    <listOptionValue builtIn="false" value="../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy"/>
                                    <listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32L4xx/Include"/>
                                    <listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
                                </option>
                                <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1778697518" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
                            </tool>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.2056636271" 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.642105406" 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.445443123" 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 id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.1064547196" 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.1325893916" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="${workspace_loc:/${ProjName}/STM32L431RCTX_FLASH.ld}" valueType="string"/>
                                <inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.2010997017" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
                                    <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
                                    <additionalInput kind="additionalinput" paths="$(LIBS)"/>
                                </inputType>
                            </tool>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.236732362" name="MCU G++ Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver.294540938" name="MCU GCC Archiver" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size.15224461" name="MCU Size" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile.460101160" name="MCU Output Converter list file" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex.209396082" name="MCU Output Converter Hex" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary.1321642423" name="MCU Output Converter Binary" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog.1741144832" name="MCU Output Converter Verilog" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec.347073685" name="MCU Output Converter Motorola S-rec" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec"/>
                            <tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec.1384506974" name="MCU Output Converter Motorola S-rec with symbols" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec"/>
                        </toolChain>
                    </folderInfo>
                    <sourceEntries>
                        <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
                        <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
                    </sourceEntries>
                </configuration>
            </storageModule>
            <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
        </cconfiguration>
    </storageModule>
    <storageModule moduleId="org.eclipse.cdt.core.pathentry"/>
    <storageModule moduleId="cdtBuildSystem" version="4.0.0">
        <project id="ISKBoard_BareMetal.null.1382914116" name="ISKBoard_BareMetal"/>
    </storageModule>
    <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
    <storageModule moduleId="scannerConfiguration">
        <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
        <scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.602940913;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.602940913.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.342548357;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1778697518">
            <autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
        </scannerConfigBuildInfo>
        <scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.859911740;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1387344889">
            <autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
        </scannerConfigBuildInfo>
    </storageModule>
    <storageModule moduleId="refreshScope"/>
    <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>
Production/ISKBoard_QCTester/.mxproject
New file
@@ -0,0 +1,37 @@
[PreviousLibFiles]
LibFiles=Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_adc_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_def.h;Drivers\STM32L4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_rcc_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_bus.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_crs.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_system.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_utils.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_flash.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_flash_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_flash_ramfunc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_dma_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dmamux.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_pwr_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_exti.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_exti.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_can.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_uart.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_usart.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_lpuart.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_uart_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_spi.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_spi_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_tim.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_tim_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_tim.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_can.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_adc_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_def.h;Drivers\STM32L4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_rcc_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_bus.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_crs.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_system.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_utils.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_flash.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_flash_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_flash_ramfunc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_dma_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dmamux.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_pwr_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_exti.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_exti.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_can.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_uart.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_usart.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_lpuart.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_uart_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_spi.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_spi_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_tim.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_tim_ex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_tim.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l431xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l4xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\system_stm32l4xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
[PreviousUsedCubeIDEFiles]
SourceFiles=Core\Src\main.c;Core\Src\gpio.c;Core\Src\adc.c;Core\Src\can.c;Core\Src\usart.c;Core\Src\spi.c;Core\Src\tim.c;Core\Src\stm32l4xx_it.c;Core\Src\stm32l4xx_hal_msp.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_can.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Core\Src\system_stm32l4xx.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_can.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Core\Src\system_stm32l4xx.c;;;
HeaderPath=Drivers\STM32L4xx_HAL_Driver\Inc;Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;Drivers\CMSIS\Device\ST\STM32L4xx\Include;Drivers\CMSIS\Include;Core\Inc;
CDefines=USE_HAL_DRIVER;STM32L431xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
[PreviousGenFiles]
AdvancedFolderStructure=true
HeaderFileListSize=9
HeaderFiles#0=..\Core\Inc\gpio.h
HeaderFiles#1=..\Core\Inc\adc.h
HeaderFiles#2=..\Core\Inc\can.h
HeaderFiles#3=..\Core\Inc\usart.h
HeaderFiles#4=..\Core\Inc\spi.h
HeaderFiles#5=..\Core\Inc\tim.h
HeaderFiles#6=..\Core\Inc\stm32l4xx_it.h
HeaderFiles#7=..\Core\Inc\stm32l4xx_hal_conf.h
HeaderFiles#8=..\Core\Inc\main.h
HeaderFolderListSize=1
HeaderPath#0=..\Core\Inc
HeaderFiles=;
SourceFileListSize=9
SourceFiles#0=..\Core\Src\gpio.c
SourceFiles#1=..\Core\Src\adc.c
SourceFiles#2=..\Core\Src\can.c
SourceFiles#3=..\Core\Src\usart.c
SourceFiles#4=..\Core\Src\spi.c
SourceFiles#5=..\Core\Src\tim.c
SourceFiles#6=..\Core\Src\stm32l4xx_it.c
SourceFiles#7=..\Core\Src\stm32l4xx_hal_msp.c
SourceFiles#8=..\Core\Src\main.c
SourceFolderListSize=1
SourcePath#0=..\Core\Src
SourceFiles=;
Production/ISKBoard_QCTester/.project
New file
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>ISKBoard_QCTester</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
            <triggers>clean,full,incremental,</triggers>
            <arguments>
            </arguments>
        </buildCommand>
        <buildCommand>
            <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
            <triggers>full,incremental,</triggers>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>com.st.stm32cube.ide.mcu.MCUProjectNature</nature>
        <nature>com.st.stm32cube.ide.mcu.MCUCubeProjectNature</nature>
        <nature>org.eclipse.cdt.core.cnature</nature>
        <nature>com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature</nature>
        <nature>com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature</nature>
        <nature>com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature</nature>
        <nature>com.st.stm32cube.ide.mcu.MCURootProjectNature</nature>
        <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
        <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
    </natures>
</projectDescription>
Production/ISKBoard_QCTester/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
New file
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
sfrviewstate={"fFavorites"\:{"fLists"\:{}},"fProperties"\:{"fNodeProperties"\:{}}}
Production/ISKBoard_QCTester/.settings/language.settings.xml
New file
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
    <configuration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984" name="Debug">
        <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
            <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
            <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
            <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
            <provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-388825680522119720" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
                <language-scope id="org.eclipse.cdt.core.gcc"/>
                <language-scope id="org.eclipse.cdt.core.g++"/>
            </provider>
        </extension>
    </configuration>
    <configuration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.602940913" name="Release">
        <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
            <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
            <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
            <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
            <provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-388825680522119720" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
                <language-scope id="org.eclipse.cdt.core.gcc"/>
                <language-scope id="org.eclipse.cdt.core.g++"/>
            </provider>
        </extension>
    </configuration>
</project>
Production/ISKBoard_QCTester/.settings/org.eclipse.cdt.core.prefs
New file
@@ -0,0 +1,6 @@
doxygen/doxygen_new_line_after_brief=true
doxygen/doxygen_use_brief_tag=false
doxygen/doxygen_use_javadoc_tags=true
doxygen/doxygen_use_pre_tag=false
doxygen/doxygen_use_structural_commands=false
eclipse.preferences.version=1
Production/ISKBoard_QCTester/.settings/stm32cubeide.project.prefs
New file
@@ -0,0 +1,4 @@
66BE74F758C12D739921AEA421D593D3=2
8DF89ED150041C4CBC7CB9A9CAA90856=97D06D5F9E071253BB07AC037B086A77
DC22A860405A8BF2F2C095E5B6529F12=97D06D5F9E071253BB07AC037B086A77
eclipse.preferences.version=1
Production/ISKBoard_QCTester/Core/Board/comport.c
New file
@@ -0,0 +1,238 @@
/* RS232/TTL/RS485 communication
 * comport.c
 *
 *  Created on: Feb 15, 2023
 *      Author: Think
 */
#include "comport.h"
#include "miscdev.h"
//#define CONFIG_COMPORT_DEBUG
#ifdef  CONFIG_COMPORT_DEBUG
#define com_print(format,args...) printf(format, ##args)
#else
#define com_print(format,args...) do{} while(0)
#endif
#define ARRAY_SIZE(x)   sizeof(x)/sizeof(x[0])
comport_t  comports[] = {
        {.fd=-1, .devname="WiFi",  .huart=&huart2   }, // ESP8266(WiFi)/ESP32(WiFi/BLE)
        {.fd=-1, .devname="RS232", .huart=&huart3   }, // RS232/TTL/MikroBUS
        {.fd=-1, .devname="RS485", .huart=&hlpuart1 }, // RS485
};
static inline comport_t *comport_find(UART_HandleTypeDef *huart)
{
    comport_t              *comport = NULL;
    int                     i;
    for(i=0; i<ARRAY_SIZE(comports); i++)
    {
        if( huart==comports[i].huart )
        {
            comport = &comports[i];
        }
    }
    return comport;
}
comport_t *comport_init(UART_HandleTypeDef *huart, uint8_t *rxch, uint8_t *rxbuf, size_t size)
{
    comport_t              *comport = NULL;
    if( !huart )
        return NULL;
    /* Find the corresponding comport in the array */
    comport = comport_find(huart);
    if( !comport )
        return NULL;
    comport->fd = 1;
    comport->huart = huart;
    comport->rxch = rxch;
    rb_init(&comport->rb, rxbuf, size);
    return comport;
}
/* +----------------------------------------+
 * | printf and interrupt receive functions |
 * +----------------------------------------+*/
/* printf callback function on USART1 */
int __io_putchar(int ch)
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}
/* USART interrupt receive callback funciton */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    comport_t              *comport = NULL;
    uint8_t                 byte;
    /* Find the corresponding comport in the array */
    comport = comport_find(huart);
    if( !comport )
    {
        goto cleanup;
    }
    /* Check comport receive ring buffer */
    if( comport->fd<0 || !comport->rb.buffer || ! rb_free_size(&comport->rb) )
    {
        goto cleanup;
    }
    /* Receive and put the byte into receive ring buffer */
    HAL_UART_Receive_IT(comport->huart, comport->rxch, 1);
    rb_write(&comport->rb, comport->rxch, 1);
    return ;
cleanup:
    HAL_UART_Receive_IT(huart, &byte, 1);
    return ;
}
/* +------------------------+
 * | UART/TTL API functions |
 * +------------------------+*/
comport_t *comport_open(UART_HandleTypeDef *huart)
{
    comport_t              *comport = NULL;
    if( !huart )
        return NULL;
    /* Find the corresponding comport in the array */
    comport = comport_find(huart);
    if( comport )
        comport->fd = 1;
    return comport;
}
void comport_flush(comport_t *comport)
{
    if( !comport || !comport->huart)
        return;
    if( comport->rb.buffer )
    {
        rb_clear( &comport->rb );
    }
    return;
}
void comport_term(comport_t *comport)
{
    if( !comport || !comport->huart)
        return;
    comport->fd = -1;
    if( comport->rb.buffer )
    {
        rb_clear( &comport->rb );
    }
    return;
}
int comport_send(comport_t *comport, char *data, int bytes)
{
    if( !comport || !data || bytes<=0 )
        return -1;
    com_print("Send %d bytes data: %s\r\n", bytes, data);
    HAL_UART_Transmit(comport->huart, (uint8_t *)data, bytes, 0xFFFF);
    return bytes;
}
int comport_recv(comport_t *comport, char *buf, int size, uint32_t timeout)
{
    uint32_t          tickstart = 0;
    size_t            bytes = 0;
    if( !comport || !buf || size<=0 )
        return -1;
    if( !comport->rb.buffer )
        return -2;
    tickstart = HAL_GetTick();
    while((HAL_GetTick() - tickstart) < timeout)
    {
        bytes = rb_data_size(&comport->rb);
        HAL_Delay( 10 );
        /* comport received data before but not receive in 10ms now, maybe data receive over */
        if( bytes>0 && rb_data_size(&comport->rb)==bytes )
        {
            break;
        }
    }
    bytes = rb_data_size(&comport->rb);
    if( !bytes )
    {
        return 0;
    }
    bytes = bytes>size ? size : bytes;
    rb_read(&comport->rb, (uint8_t *)buf, bytes);
    com_print("Receive %d bytes data: %s\r\n", bytes, buf);
    return bytes;
}
/* +------------------------+
 * |   RS485 API functions  |
 * +------------------------+*/
/* Direction Pin set to be high level will be send mode, and low level will be receive mode */
#define rs485_set_dirTx()   HAL_GPIO_WritePin(RS485_Dir_GPIO_Port, RS485_Dir_Pin, GPIO_PIN_SET)
#define rs485_set_dirRx()   HAL_GPIO_WritePin(RS485_Dir_GPIO_Port, RS485_Dir_Pin, GPIO_PIN_RESET)
comport_t *rs485_open(UART_HandleTypeDef *huart)
{
    return comport_find(huart);
}
void rs485_term(comport_t *comport)
{
    return comport_term(comport);
}
int rs485_send(comport_t *comport, char *data, int bytes)
{
    int             rv;
    rs485_set_dirTx();
    rv = comport_send(comport, data, bytes);
    rs485_set_dirRx();
    return rv;
}
int rs485_recv(comport_t *comport, char *buf, int size, uint32_t timeout)
{
    rs485_set_dirRx();
    return comport_recv(comport, buf, size, timeout);
}
Production/ISKBoard_QCTester/Core/Board/comport.h
New file
@@ -0,0 +1,45 @@
/*
 * comport.h
 *
 *  Created on: Feb 15, 2023
 *      Author: Think
 */
#ifndef INC_COMPORT_H_
#define INC_COMPORT_H_
/* Library includes. */
#include "stm32l4xx_hal.h"
/* Demo application includes. */
#include <stdio.h>
#include "usart.h"
#include "ringbuf.h"
#define COMM_RXBUFSIZE          1024
typedef struct comport_s
{
    int                       fd;              /* compatible with Linux API */
    char                      devname[32];     /* UART device name */
    UART_HandleTypeDef       *huart;           /* STM32 UART Handler */
    uint8_t                  *rxch;            /* receive data in interrupt handler */
    ring_buffer_t             rb;              /* receive data ring buffer */
} comport_t;
comport_t *comport_init(UART_HandleTypeDef *huart, uint8_t *rxch, uint8_t *rxbuf, size_t size);
comport_t *comport_open(UART_HandleTypeDef *huart);
void comport_flush(comport_t *comport);
extern int comport_send(comport_t *comport, char *data, int bytes);
extern int comport_recv(comport_t *comport, char *buf, int size, uint32_t timeout);
extern void comport_term(comport_t *comport);
extern comport_t *rs485_open(UART_HandleTypeDef *huart);
extern int rs485_send(comport_t *comport, char *data, int bytes);
extern int rs485_recv(comport_t *comport, char *buf, int size, uint32_t timeout);
extern void rs485_term(comport_t *comport);
#endif /* INC_WIRED_H_ */
Production/ISKBoard_QCTester/Core/Board/ds18b20.c
New file
@@ -0,0 +1,237 @@
/*
 * ds18b20.c
 *
 *  Created on: 2021年8月17日
 *      Author: Think
 */
#include "main.h"
#include "miscdev.h"
typedef struct w1_gpio_s
{
    GPIO_TypeDef        *group;
    uint16_t             pin;
} w1_gpio_t;
static w1_gpio_t   W1Dat =  /* IO pin connected to PA12 */
{
        .group = GPIOA,
        .pin   = GPIO_PIN_12,
};
#define W1DQ_Input()           \
{    \
        GPIO_InitTypeDef GPIO_InitStruct = {0}; \
        GPIO_InitStruct.Pin = W1Dat.pin; \
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT; \
        GPIO_InitStruct.Pull = GPIO_PULLUP; \
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; \
        HAL_GPIO_Init(W1Dat.group, &GPIO_InitStruct); \
}
#define W1DQ_Output()           \
{    \
        GPIO_InitTypeDef GPIO_InitStruct = {0}; \
        GPIO_InitStruct.Pin = W1Dat.pin; \
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; \
        GPIO_InitStruct.Pull = GPIO_NOPULL; \
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; \
        HAL_GPIO_Init(W1Dat.group, &GPIO_InitStruct); \
}
#define W1DQ_Write(x)    HAL_GPIO_WritePin(W1Dat.group, W1Dat.pin, \
                        (x==1)?GPIO_PIN_SET:GPIO_PIN_RESET)
#define W1DQ_Read()     HAL_GPIO_ReadPin(W1Dat.group,  W1Dat.pin)
/* Master issues reset pulse and DS18B20s respond with presence pulse */
uint8_t ds18b20_reset(void)
{
    uint8_t            rv = 0;
    uint8_t            retry;
    /* Setup W1 DQ pin as output and high level*/
    W1DQ_Output();
    W1DQ_Write(1);
    delay_us(2);
    /* Reset pulse by pulling the DQ pin low >=480us */
    W1DQ_Write(0);
    delay_us(480);
    /* Master releases bus to high. When DS18B20 detects this rising edge, it waits 15µs to 60µs */
    W1DQ_Write(1);
    delay_us(60);
    /* Then DS18B20 transmits a presence pulse by pulling the W1 bus low for 60µs to 240µs */
    while( W1DQ_Read() && retry <240)
    {
        retry++;
        delay_us(1);
    }
    if(retry >= 240)
        rv = 1;
    delay_us(240);
    /* Master Rx time must >= 480us */
    W1DQ_Output();
    W1DQ_Write(1);
    delay_us(240);
    return rv;
}
void ds18b20_write(uint8_t byte)
{
    uint8_t            i = 0;
    W1DQ_Output();
    for(i=0; i<8; i++)
    {
        /* Write 1: pull low <= 15us, Write 0: pull low 15~60us*/
        W1DQ_Write(0);
        delay_us(10);
        /* DS18B20 bit sent by LSB (lower bit first) */
        if( byte & 0x1 )
            W1DQ_Write(1);
        else
            W1DQ_Write(0);
        /* Write 1/0 slot both >= 60us, hold the level for 60us */
        delay_us(60);
        /* Release W1 bus to high */
        W1DQ_Write(1);
        delay_us(2);
        /* Prepare for next bit */
        byte >>= 1;
    }
}
uint8_t ds18b20_read(void)
{
    uint8_t            i = 0;
    uint8_t            byte = 0;
    for(i=0; i<8; i++)
    {
        /* Read time slot is initiated by master pulling the W1 bus
         * low for minimum of 1µs and then releasing the bus */
        W1DQ_Output();
        W1DQ_Write(0);
        delay_us(2);
        W1DQ_Write(1);
        delay_us(2);
        /* After master initiates read time slot, DS18B20 will begin
         * transmitting a 1 or 0 on bus */
        W1DQ_Input();
        /* DS18B20 bit sent by LSB (lower bit first) */
        if( W1DQ_Read() )
        {
            byte |= 1<<i;
        }
        /* Read slot for >= 60us */
        delay_us(60);
        /* Release W1 bus to high */
        W1DQ_Output();
        W1DQ_Write(1);
        delay_us(2);
    }
    return byte;
}
static inline int ds18b20_start_convert(void)
{
    /* Master issues reset pulse and DS18B20s respond with presence pulse */
    if( 0 != ds18b20_reset() )
        return -1;
    /* Master issues Skip ROM command */
    ds18b20_write(0xCC);
    /* Master issues Convert T command. */
    ds18b20_write(0x44);
    return 0;
}
static inline int ds18b20_start_read(uint8_t *buf, int bytes)
{
    /* Master issues reset pulse and DS18B20s respond with presence pulse */
    if( 0 != ds18b20_reset() )
        return -1;
    /* Master issues Skip ROM command */
    ds18b20_write(0xCC);
    /* Master issues Read Scratchpad command. */
    ds18b20_write(0xBE);
    buf[0] = ds18b20_read();   /* Temperature LSB */
    buf[1] = ds18b20_read();   /* Temperature MSB */
    /*Don't care followed 7 bytes data */
    return 0;
}
int ds18b20_sample(float *temperature)
{
    uint8_t               byte[2];
    uint8_t               sign;
    uint16_t              temp;
    static uint8_t        firstin = 1;
    if( !temperature )
        return -1;
    if( 0 != ds18b20_start_convert() )
        return -2;
    /* First sample need 750ms delay */
    if( firstin )
    {
        HAL_Delay(750);
        firstin = 0;
    }
    if( 0 != ds18b20_start_read(byte, 2) )
        return -3;
    /* Temperature byte[0] is LSB, byte[1] is MSB, total 16 bit:
     * Byte[0]:  bit[3:0]: decimal bits,  bit[7:4]: integer bits
     * bYTE[1]:  bit[2:0]: integer bits,  bit[7:3]: sign bits
     */
    if( byte[1]> 0x7 ) /* bit[7:3] is 1 */
    {
        temp = ~(byte[1]<<8|byte[0]) + 1;  //补码
        sign=0; //温度为负
    }
    else
    {
        sign=1;//温度为正
        temp = byte[1]<<8 | byte[0];
    }
   /* byte[1]的低三位和byte[0]的高四位组成温度值的整数部分,
    * 而byte[0]的低四位为小数精度部分,且精度系数为0.0625 */
    *temperature = (temp>>4) + (temp&0xF)*0.0625 ;
    if( !sign )
    {
        *temperature = -*temperature;
    }
    return 0;
}
Production/ISKBoard_QCTester/Core/Board/ds18b20.h
New file
@@ -0,0 +1,13 @@
/*
 * ds18b20.h
 *
 *  Created on: Dec 31, 2022
 *      Author: Think
 */
#ifndef INC_DS18B20_H_
#define INC_DS18B20_H_
extern int ds18b20_sample(float *temperature);
#endif /* INC_DS18B20_H_ */
Production/ISKBoard_QCTester/Core/Board/font_oled.h
New file
@@ -0,0 +1,205 @@
#ifndef __FONT_OLED_H
#define __FONT_OLED_H
#include <stdint.h>
/************************************ ASCII font size 6x8 ************************************/
static const uint8_t F6x8[][6] =
{
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// sp
    {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00},// !
    {0x00, 0x00, 0x07, 0x00, 0x07, 0x00},// "
    {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14},// #
    {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12},// $
    {0x00, 0x62, 0x64, 0x08, 0x13, 0x23},// %
    {0x00, 0x36, 0x49, 0x55, 0x22, 0x50},// &
    {0x00, 0x00, 0x05, 0x03, 0x00, 0x00},// '
    {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00},// (
    {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00},// )
    {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14},// *
    {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08},// +
    {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00},// ,
    {0x00, 0x08, 0x08, 0x08, 0x08, 0x08},// -
    {0x00, 0x00, 0x60, 0x60, 0x00, 0x00},// .
    {0x00, 0x20, 0x10, 0x08, 0x04, 0x02},// /
    {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
    {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00},// 1
    {0x00, 0x42, 0x61, 0x51, 0x49, 0x46},// 2
    {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31},// 3
    {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10},// 4
    {0x00, 0x27, 0x45, 0x45, 0x45, 0x39},// 5
    {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
    {0x00, 0x01, 0x71, 0x09, 0x05, 0x03},// 7
    {0x00, 0x36, 0x49, 0x49, 0x49, 0x36},// 8
    {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E},// 9
    {0x00, 0x00, 0x36, 0x36, 0x00, 0x00},// :
    {0x00, 0x00, 0x56, 0x36, 0x00, 0x00},// ;
    {0x00, 0x08, 0x14, 0x22, 0x41, 0x00},// <
    {0x00, 0x14, 0x14, 0x14, 0x14, 0x14},// =
    {0x00, 0x00, 0x41, 0x22, 0x14, 0x08},// >
    {0x00, 0x02, 0x01, 0x51, 0x09, 0x06},// ?
    {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E},// @
    {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C},// A
    {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36},// B
    {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22},// C
    {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C},// D
    {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41},// E
    {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01},// F
    {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A},// G
    {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F},// H
    {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00},// I
    {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01},// J
    {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41},// K
    {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40},// L
    {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F},// M
    {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F},// N
    {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E},// O
    {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06},// P
    {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E},// Q
    {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46},// R
    {0x00, 0x46, 0x49, 0x49, 0x49, 0x31},// S
    {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01},// T
    {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F},// U
    {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F},// V
    {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F},// W
    {0x00, 0x63, 0x14, 0x08, 0x14, 0x63},// X
    {0x00, 0x07, 0x08, 0x70, 0x08, 0x07},// Y
    {0x00, 0x61, 0x51, 0x49, 0x45, 0x43},// Z
    {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00},// [
    {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55},// 55
    {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00},// ]
    {0x00, 0x04, 0x02, 0x01, 0x02, 0x04},// ^
    {0x00, 0x40, 0x40, 0x40, 0x40, 0x40},// _
    {0x00, 0x00, 0x01, 0x02, 0x04, 0x00},// '
    {0x00, 0x20, 0x54, 0x54, 0x54, 0x78},// a
    {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38},// b
    {0x00, 0x38, 0x44, 0x44, 0x44, 0x20},// c
    {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F},// d
    {0x00, 0x38, 0x54, 0x54, 0x54, 0x18},// e
    {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02},// f
    {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C},// g
    {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78},// h
    {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00},// i
    {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00},// j
    {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00},// k
    {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00},// l
    {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78},// m
    {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78},// n
    {0x00, 0x38, 0x44, 0x44, 0x44, 0x38},// o
    {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18},// p
    {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC},// q
    {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08},// r
    {0x00, 0x48, 0x54, 0x54, 0x54, 0x20},// s
    {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20},// t
    {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C},// u
    {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C},// v
    {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C},// w
    {0x00, 0x44, 0x28, 0x10, 0x28, 0x44},// x
    {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C},// y
    {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44},// z
    {0x14, 0x14, 0x14, 0x14, 0x14, 0x14},// horiz lines
};
/************************************ ASCII font size 8x16 ************************************/
static const uint8_t F8X16[]=
{
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//  0
    0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
    0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
    0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
    0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
    0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
    0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
    0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
    0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
    0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
    0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
    0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
    0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
    0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
    0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
    0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
    0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
    0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
    0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
    0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
    0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
    0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
    0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
    0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
    0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
    0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
    0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
    0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
    0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
    0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
    0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
    0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
    0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
    0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
    0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
    0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
    0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
    0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
    0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
    0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
    0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
    0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
    0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
    0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
    0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
    0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
    0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
    0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
    0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
    0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
    0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
    0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
    0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
    0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
    0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
    0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
    0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
    0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
    0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
    0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
    0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
    0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
    0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
    0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
    0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
    0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
    0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
    0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
    0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
    0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
    0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
    0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
    0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
    0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
    0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
    0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
    0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
    0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
    0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
    0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
    0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
    0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
    0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
    0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
    0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
    0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
    0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
    0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
    0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
    0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};
#endif
Production/ISKBoard_QCTester/Core/Board/hal_oled.c
New file
@@ -0,0 +1,280 @@
/**********************************************************************
*   Copyright: (C)2021 LingYun IoT System Studio <www.weike-iot.com>
*      Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292
* Description: BearKE1 NB-IoT Board OLED Hardware Abstract Layer source code
*
*   ChangeLog:
*        Version    Date       Author            Description
*        V1.0.0  2021.08.10  GuoWenxue      Release initial version
***********************************************************************/
#include "hal_oled.h"
enum
{
    OLED_CMD = 0,
    OLED_DATA,
};
static void IIC_Write_Command(uint8_t command)
{
    /* Send I2C start signal */
    I2C_StartCondition(OLED_I2CBUS);
    /* Send OLED I2C slave write address */
    I2C_SendAddress(OLED_I2CBUS, I2C_WR);
    /* send command value */
    I2C_WriteByte(OLED_I2CBUS, 0x00);
    I2C_WriteByte(OLED_I2CBUS, command);
    /* Send I2C stop signal */
    I2C_StopCondition(OLED_I2CBUS);
}
static void IIC_Write_Data(uint8_t data)
{
    /* Send I2C start signal */
    I2C_StartCondition(OLED_I2CBUS);
    /* Send OLED I2C slave write address */
    I2C_SendAddress(OLED_I2CBUS, I2C_WR);
    /* send data value */
    I2C_WriteByte(OLED_I2CBUS, 0x40);
    I2C_WriteByte(OLED_I2CBUS, data);
    /* Send I2C stop signal */
    I2C_StopCondition(OLED_I2CBUS);
}
 /* OLED write a byte command data or command */
void OLED_WR_Byte(uint8_t data, uint8_t type)
{
    if( OLED_CMD==type )
    {
        IIC_Write_Command(data);
    }
    else
    {
        IIC_Write_Data(data);
    }
}
/*
 *+-------------------------------------------------+
 *|        OLED initial/control function API        |
 *+-------------------------------------------------+
 */
/* Turn OLED display onʾ */
void OLED_Display_On(void)
{
    OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDC command
    OLED_WR_Byte(0X14, OLED_CMD);  //DCDC ON
    OLED_WR_Byte(0XAF, OLED_CMD);  //DISPLAY ON
}
/* Turn OLED display off */
void OLED_Display_Off(void)
{
    OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDC command
    OLED_WR_Byte(0X10, OLED_CMD);  //DCDC OFF
    OLED_WR_Byte(0XAE, OLED_CMD);  //DISPLAY OFF
}
/* Clear OLED, it will be black */
void OLED_Clear(void)
{
    uint8_t   i, j;
    /* update display */
    for(i=0;i<8;i++)
    {
        OLED_WR_Byte (0xb0+i, OLED_CMD);    // set page address: 0~7
        OLED_WR_Byte (0x00, OLED_CMD);      // set display address, column address lower bytes;ַ
        OLED_WR_Byte (0x10, OLED_CMD);      // set display address, column address higher bytes;
        for(j=0; j<128; j++)
            OLED_WR_Byte(0, OLED_DATA);
    }
    OLED_Set_Pos(0, 0);
}
void OLED_On(void)
{
    uint8_t   i, j;
    /* update display */
    for(i=0; i<8; i++)
    {
        OLED_WR_Byte (0xb0+i, OLED_CMD);    // set page address: 0~7
        OLED_WR_Byte (0x00, OLED_CMD);      // set display address, row address lower bytes;ַ
        OLED_WR_Byte (0x10, OLED_CMD);      // set display address, row address higher bytes;
        for(j=0; j<128; j++)
            OLED_WR_Byte(1, OLED_DATA);
    }
}
void OLED_Init(void)
{
    if( i2c_init(OLED_I2CBUS, OLED_CHIPADDR) )
    {
        return ;
    }
    HAL_Delay(200);
    OLED_WR_Byte(0xAE,OLED_CMD); // Disable
    OLED_WR_Byte(0x40,OLED_CMD); //---set low column address
    OLED_WR_Byte(0xB0,OLED_CMD); //---set high column address
    OLED_WR_Byte(0xC8,OLED_CMD);
    OLED_WR_Byte(0x81,OLED_CMD);
    OLED_WR_Byte(0xff,OLED_CMD);
    OLED_WR_Byte(0xa1,OLED_CMD);
    OLED_WR_Byte(0xa6,OLED_CMD);
    OLED_WR_Byte(0xa8,OLED_CMD);
    OLED_WR_Byte(0x1f,OLED_CMD);
    OLED_WR_Byte(0xd3,OLED_CMD);
    OLED_WR_Byte(0x00,OLED_CMD);
    OLED_WR_Byte(0xd5,OLED_CMD);
    OLED_WR_Byte(0xf0,OLED_CMD);
    OLED_WR_Byte(0xd9,OLED_CMD);
    OLED_WR_Byte(0x22,OLED_CMD);
    OLED_WR_Byte(0xda,OLED_CMD);
    OLED_WR_Byte(0x02,OLED_CMD);
    OLED_WR_Byte(0xdb,OLED_CMD);
    OLED_WR_Byte(0x49,OLED_CMD);
    OLED_WR_Byte(0x8d,OLED_CMD);
    OLED_WR_Byte(0x14,OLED_CMD);
    OLED_WR_Byte(0xaf,OLED_CMD);
    OLED_Clear();
}
/*
 *+-------------------------------------------------+
 *|          OLED display function API              |
 *+-------------------------------------------------+
 */
/* set OLED display position */
void OLED_Set_Pos(uint8_t x, uint8_t y)
{
    OLED_WR_Byte(0xb0+y, OLED_CMD);
    OLED_WR_Byte(((x&0xf0)>>4)|0x10, OLED_CMD);
    OLED_WR_Byte((x&0x0f), OLED_CMD);
}
/* show a character on OLED as $Char_Size */
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t char_Size)
{
    uint8_t c=0,i=0;
    c=chr-' ';  // get offset value
    if( x>X_WIDTH-1 )
    {
        x=0;
        y=y+2;
    }
    if(char_Size ==16)
    {
        OLED_Set_Pos(x,y);
        for(i=0; i<8; i++)
            OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
        OLED_Set_Pos(x,y+1);
        for(i=0;i<8;i++)
            OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
    }
    else
    {
        OLED_Set_Pos(x,y);
        for(i=0;i<6;i++)
            OLED_WR_Byte(F6x8[c][i],OLED_DATA);
    }
}
/* show a string on OLED  */
void OLED_ShowString(uint8_t x, uint8_t y, char *chr, uint8_t font_size)
{
    uint8_t     j=0;
    while( chr[j]!='\0' )
    {
        OLED_ShowChar(x, y, chr[j], font_size);
        x+=8;
        if(x>120)
        {
            x=0;
            y+=2;
        }
        j++;
    }
}
/* Show Chinese on OLED */
void OLED_ShowChinese(uint8_t (*Hzk)[32], uint8_t x, uint8_t y, uint8_t no)
{
    uint8_t         t,adder=0;
    OLED_Set_Pos(x, y);
    for(t=0;t<16;t++)
    {
        OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
        adder+=1;
    }
    OLED_Set_Pos(x,y+1);
    for(t=0;t<16;t++)
    {
        OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
        adder+=1;
    }
}
/* Show BMP images(128x64) on OLED, x: 0~127  y:0~7 */
void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *BMP)
{
    uint32_t         j=0;
    uint8_t         x,y;
    if( y1%8==0 )
        y = y1/8;
    else
        y = y1/8+1;
    for(y=y0; y<y1; y++)
    {
        OLED_Set_Pos(x0, y);
        for(x=x0;x<x1;x++)
        {
            OLED_WR_Byte(BMP[j++],OLED_DATA);
        }
    }
}
Production/ISKBoard_QCTester/Core/Board/hal_oled.h
New file
@@ -0,0 +1,45 @@
/*
 * oled.h
 *
 *  Created on: 2023年1月20日
 *      Author: Wenxue
 */
#ifndef INC_HAL_OLED_H_
#define INC_HAL_OLED_H_
#include "stm32l4xx_hal.h"
#include "i2c_bitbang.h"
#include "font_oled.h"
#define OLED_I2CBUS                I2CBUS0   /* OLED on GPIO I2C bus0 */
#define OLED_CHIPADDR              0x3C      /* OLED chip address */
#define X_WIDTH                    128
#define Y_WIDTH                    64
#define OLED_FONT16                16
#define OLED_FONT8                 8
/*
 *+-------------------------------------------------+
 *|        OLED initial/control function API        |
 *+-------------------------------------------------+
 */
void OLED_Init(void);
void OLED_On(void);
void OLED_Clear(void);
void OLED_Display_On(void);
void OLED_Display_Off(void);
/*
 *+-------------------------------------------------+
 *|          OLED display function API              |
 *+-------------------------------------------------+
 */
void OLED_Set_Pos(uint8_t x, uint8_t y);
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size);
void OLED_ShowString(uint8_t x,uint8_t y, char *p,uint8_t font_size);
#endif /* INC_HAL_OLED_H_ */
Production/ISKBoard_QCTester/Core/Board/i2c_bitbang.c
New file
@@ -0,0 +1,354 @@
/*
 * i2c_bitbang.c
 *
 *  Created on: Jan 19, 2023
 *      Author: Wenxue
 */
#include "i2c_bitbang.h"
i2c_bus_t i2c_bus[I2CBUSMAX] =
{
    /* Bus   ChipAddr       SCL_Pin              SDA_Pin      */
    {I2CBUS0, 0x00, {GPIOB, GPIO_PIN_6 }, {GPIOB, GPIO_PIN_7 } }, /* SHT20, RTC, OLED */
    {I2CBUS1, 0x00, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11} }, /* MikroBUS I2C interface */
};
enum
{
    LOW,
    HIGH,
};
/*+--------------------------+
 *|    Low level GPIO API    |
 *+--------------------------+*/
static inline void SDA_IN(uint8_t bus)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = i2c_bus[bus].sda.pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(i2c_bus[bus].sda.group, &GPIO_InitStruct);
}
static inline void SDA_OUT(uint8_t bus)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = i2c_bus[bus].sda.pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(i2c_bus[bus].sda.group, &GPIO_InitStruct);
}
static inline void SCL_OUT(uint8_t bus)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = i2c_bus[bus].scl.pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(i2c_bus[bus].scl.group, &GPIO_InitStruct);
}
static inline void SCL_SET(uint8_t bus, int level)
{
    HAL_GPIO_WritePin(i2c_bus[bus].scl.group, i2c_bus[bus].scl.pin, level?GPIO_PIN_SET:GPIO_PIN_RESET);
}
static inline void SDA_SET(uint8_t bus, int level)
{
    HAL_GPIO_WritePin(i2c_bus[bus].sda.group, i2c_bus[bus].sda.pin, level?GPIO_PIN_SET:GPIO_PIN_RESET);
}
static inline GPIO_PinState SCL_GET(uint8_t bus)
{
    return HAL_GPIO_ReadPin(i2c_bus[bus].scl.group, i2c_bus[bus].scl.pin);
}
static inline GPIO_PinState SDA_GET(uint8_t bus)
{
    return HAL_GPIO_ReadPin(i2c_bus[bus].sda.group, i2c_bus[bus].sda.pin);
}
/*+--------------------------+
 *|  I2C Clock Sequence API  |
 *+--------------------------+*/
/* */
#if 1
#include "miscdev.h"  /* delay_us() implement by TIM6 */
#else
static inline void delay_us(uint32_t us)
{
    uint32_t      i, j;
    for(j=0; j<450; j++)// 450 ~500
        for(i = 0; i < us; i++)
        {
            __NOP();
        }
}
#endif
void I2C_StartCondition(uint8_t bus)
{
    SDA_OUT(bus);
    SCL_OUT(bus);
    /* Start Condition Clock Sequence:
              ______
     SCL:           |___
            _____
     SDA:        |_____
    */
    SDA_SET(bus, HIGH);
    SCL_SET(bus, HIGH);
    delay_us(1);
    SDA_SET(bus, LOW);
    delay_us(1);  // hold time start condition (t_HD;STA)
    SCL_SET(bus, LOW);
    delay_us(1);
}
void I2C_StopCondition(uint8_t bus)
{
    SDA_OUT(bus);
    /* SCL Stop Condition Clock Sequence:
                _______
      SCL:   ___|
                   _____
      SDA:   _____|
    */
    SCL_SET(bus, LOW);
    SDA_SET(bus, LOW);
    delay_us(1);
    SCL_SET(bus, HIGH);
    SDA_SET(bus, HIGH);
    delay_us(1);
}
void I2C_Ack(uint8_t bus, uint8_t ack)
{
    if(ACK_NONE == ack)
        return ;
    SCL_SET(bus, LOW);
    SDA_OUT(bus);
    if( ACK==ack )
        SDA_SET(bus, LOW);
    else if( NAK==ack )
        SDA_SET(bus, HIGH);
    delay_us(1);
    SCL_SET(bus, HIGH);
    delay_us(1);
    SCL_SET(bus, LOW);
}
uint8_t I2C_WriteByte(uint8_t bus, uint8_t txByte)
{
    uint8_t error = NO_ERROR;
    uint8_t mask;
    SDA_OUT(bus);
    SCL_SET(bus, LOW);
    /* start send 8 bits data */
    for(mask=0x80; mask>0; mask>>=1)
    {
        if((mask & txByte) == 0)
            SDA_SET(bus, LOW);
        else
            SDA_SET(bus, HIGH);
        delay_us(1);    // data set-up time (t_SU;DAT)
        SCL_SET(bus, HIGH);
        delay_us(1);    // SCL high time (t_HIGH)
        SCL_SET(bus, LOW);
        delay_us(1);    // data hold time(t_HD;DAT)
    }
    /* Wait for ACK/NAK */
    SDA_IN(bus);
    SCL_SET(bus, HIGH); // clk #9 for ack
    delay_us(1); // data set-up time (t_SU;DAT)
    /* High level means NAK */
    if( SDA_GET(bus) )
        error = ACK_ERROR;
    SCL_SET(bus, LOW);
    delay_us(1);
    return error;
}
static inline uint8_t I2C_WaitWhileClockStreching(uint8_t bus, uint8_t timeout)
{
    uint8_t error = NO_ERROR;
    while( SCL_GET(bus)== 0)
    {
        if(timeout-- == 0)
            return TIMEOUT_ERROR;
        delay_us(10);
    }
    return error;
}
uint8_t I2C_ReadByte(uint8_t bus, uint8_t *rxByte, uint8_t ack, uint32_t timeout)
{
//==============================================================================
    uint8_t error = NO_ERROR;
    uint8_t mask;
    *rxByte = 0x00;
    SDA_IN(bus);
    /* start read 8 bits data */
    for(mask = 0x80; mask > 0; mask >>= 1)
    {
        SCL_SET(bus, HIGH);  // start clock on SCL-line
        delay_us(1);         // clock set-up time (t_SU;CLK)
        // wait while clock streching
        error = I2C_WaitWhileClockStreching(bus, timeout);
        delay_us(1); // SCL high time (t_HIGH)
        if( SDA_GET(bus) )
            *rxByte |= mask; // read bit
        SCL_SET(bus, LOW);
        delay_us(1); // data hold time(t_HD;DAT)
    }
    I2C_Ack(bus, ack);
  return error;
}
uint8_t I2C_SendAddress(uint8_t bus, uint8_t dir)
{
    uint8_t       addr;
    uint8_t       rv;
    if( I2C_WR == dir )
    {
        addr = W_ADDR(i2c_bus[bus].addr);
    }
    else
    {
        addr = R_ADDR(i2c_bus[bus].addr);
    }
    rv=I2C_WriteByte(bus, addr);
    return rv;
}
int i2c_init(uint8_t bus, uint8_t addr)
{
    if( bus >= I2CBUSMAX )
    {
        return -1;
    }
#if 0
    /* I2C bus used already */
    if( 0x00 != i2c_bus[bus].addr )
    {
        return -2;
    }
#endif
    /* Set I2C slave address */
    i2c_bus[bus].addr = addr;
    return 0;
}
int i2c_term(uint8_t bus)
{
    if( bus >= I2CBUSMAX )
    {
        return -1;
    }
    /* Set I2C slave address */
    i2c_bus[bus].addr = 0x0;
    return 0;
}
int i2c_read(uint8_t bus, uint8_t *buf, int size)
{
  int       i;
  int       rv = NO_ERROR;
    uint8_t   byte;
  I2C_StartCondition(bus);
  if( NO_ERROR != (rv=I2C_SendAddress(bus, I2C_RD) ) )
  {
    goto OUT;
  }
  for (i=0; i<size; i++)
  {
     if( !I2C_ReadByte(bus, &byte, ACK, I2C_CLK_STRETCH_TIMEOUT) )
             buf[i] = byte;
         else
             goto OUT;
  }
OUT:
  I2C_StopCondition(bus);
  return rv;
}
int i2c_write(uint8_t bus, uint8_t *data, int bytes)
{
  int       i;
  int       rv = NO_ERROR;
    if(!data)
        return PARM_ERROR;
  I2C_StartCondition(bus);
  if( NO_ERROR != (rv=I2C_SendAddress(bus, I2C_WR)) )
  {
    goto OUT;
  }
  for (i=0; i<bytes; i++)
  {
    if( NO_ERROR != (rv=I2C_WriteByte(bus, data[i])) )
    {
      break;
    }
  }
OUT:
  I2C_StopCondition(bus);
  return rv;
}
Production/ISKBoard_QCTester/Core/Board/i2c_bitbang.h
New file
@@ -0,0 +1,84 @@
/*
 * i2c_bitbang.h
 *
 *  Created on: Jan 19, 2023
 *      Author: Wenxue
 */
#ifndef INC_I2C_BITBANG_H_
#define INC_I2C_BITBANG_H_
#include "stm32l4xx_hal.h"
#define I2C_CLK_STRETCH_TIMEOUT      6000
typedef enum i2c_num_e
{
    I2CBUS0,
    I2CBUS1,
    I2CBUSMAX,
} i2c_num_t;
typedef struct i2c_gpio_s
{
    GPIO_TypeDef        *group; /* GPIO group */
    uint16_t             pin;   /* GPIO pin   */
} i2c_gpio_t;
typedef struct i2c_bus_s
{
    uint8_t             bus;  /* Bus number   */
    uint8_t             addr; /* Chip 7bits address */
    i2c_gpio_t          scl;  /* SCL GPIO pin */
    i2c_gpio_t          sda;  /* SDA GPIO pin */
} i2c_bus_t;
/*
 *+---------------------+
 *|  I2C API functions  |
 *+---------------------+
 */
/* I2C bus error number */
enum{
  NO_ERROR       = 0x00, // no error
  ACK_ERROR      = 0x01, // no acknowledgment error
  CHECKSUM_ERROR = 0x02, // checksum mismatch error
  TIMEOUT_ERROR  = 0x04, // timeout error
  PARM_ERROR     = 0x80, // parameter out of range error
};
extern int i2c_init(uint8_t bus, uint8_t addr);
extern int i2c_term(uint8_t bus);
extern int i2c_read(uint8_t bus, uint8_t *buf, int size);
extern int i2c_write(uint8_t bus, uint8_t *data, int bytes);
extern void I2C_StartCondition(uint8_t bus);
extern void I2C_StopCondition(uint8_t bus);
/* I2C从设备芯片器件读写方向位器件地址 */
#define R_ADDR(x)     ((x)<<1 | 1) /* I2C地址最低位为1表示读 */
#define W_ADDR(x)     ((x)<<1 )    /* I2C地址最低位为0表示写 */
enum
{
    I2C_WR,     /* 写方向 */
    I2C_RD,  /* 读方向 */
};
extern uint8_t I2C_SendAddress(uint8_t bus, uint8_t dir);
extern uint8_t I2C_WriteByte(uint8_t bus, uint8_t txByte);
enum
{
    ACK_NONE, /* 不回ACK */
    ACK,      /* 回ACK */
    NAK,      /* 回NAK */
};
extern uint8_t I2C_ReadByte(uint8_t bus, uint8_t *rxByte, uint8_t ack, uint32_t timeout);
#endif /* INC_I2C_BITBANG_H_ */
Production/ISKBoard_QCTester/Core/Board/isl1208.c
New file
@@ -0,0 +1,329 @@
/*
 * sht20.c
 *
 *  Created on: Jan 19, 2023
 *      Author: Wenxue
 */
#include <stdio.h>
#include <string.h>
#include "isl1208.h"
/*+--------------------------------------+
 *|      RTC Chipset ISL1208 Register    |
 *+--------------------------------------+*/
/* rtc section */
#define ISL1208_REG_SC            0x00
#define ISL1208_REG_MN            0x01
#define ISL1208_REG_HR            0x02
#define ISL1208_REG_HR_MIL     (1<<7)   /* 24h/12h mode */
#define ISL1208_REG_HR_PM      (1<<5)   /* PM/AM bit in 12h mode */
#define ISL1208_REG_DT            0x03
#define ISL1208_REG_MO            0x04
#define ISL1208_REG_YR            0x05
#define ISL1208_REG_DW            0x06
#define ISL1208_RTC_SECTION_LEN    7 /* RTC Section register */
#define REGS_RTC_SR_LEN            8 /* RTC Section and status register  */
/* control/status section */
#define ISL1208_REG_SR            0x07
#define ISL1208_REG_SR_ARST    (1<<7)   /* auto reset */
#define ISL1208_REG_SR_XTOSCB  (1<<6)   /* crystal oscillator */
#define ISL1208_REG_SR_WRTC    (1<<4)   /* write rtc */
#define ISL1208_REG_SR_EVT     (1<<3)   /* event */
#define ISL1208_REG_SR_ALM     (1<<2)   /* alarm */
#define ISL1208_REG_SR_BAT     (1<<1)   /* battery */
#define ISL1208_REG_SR_RTCF    (1<<0)   /* rtc fail */
#define ISL1208_REG_INT            0x08
#define ISL1208_REG_INT_ALME   (1<<6)   /* alarm enable */
#define ISL1208_REG_INT_IM     (1<<7)   /* interrupt/alarm mode */
#define ISL1219_REG_EV            0x09
#define ISL1219_REG_EV_EVEN    (1<<4)   /* event detection enable */
#define ISL1219_REG_EV_EVIENB  (1<<7)   /* event in pull-up disable */
#define ISL1208_REG_ATR            0x0a
#define ISL1208_REG_DTR            0x0b
/* alarm section */
#define ISL1208_REG_SCA            0x0c
#define ISL1208_REG_MNA            0x0d
#define ISL1208_REG_HRA            0x0e
#define ISL1208_REG_DTA            0x0f
#define ISL1208_REG_MOA            0x10
#define ISL1208_REG_DWA            0x11
#define ISL1208_ALARM_SECTION_LEN 6
/* user section */
#define ISL1208_REG_USR1        0x12
#define ISL1208_REG_USR2        0x13
#define ISL1208_USR_SECTION_LEN    2
#define ISL1208_REGS_MAX        0x13
const char *weekday[7]={"Sun.","Mon.","Tue.","Wed.","Thu.","Fri.","Sat." };
#define CONFIG_RTC_DEBUG
#ifdef  CONFIG_RTC_DEBUG
#define rtc_print(format,args...) printf(format, ##args)
#else
#define rtc_print(format,args...) do{} while(0)
#endif
#ifdef CONFIG_RTC_DEBUG
__attribute__((unused)) static void dump_buf(const char *prompt, uint8_t *buf, uint32_t size)
{
    int      i;
    if(!buf)
        return ;
    if(prompt)
        printf("%s\r\n", prompt);
    for(i=0; i<size; i++)
        printf("%02x ", buf[i]);
    printf("\r\n");
}
#endif
/*
 *+----------------------------------+
 *|     ISL1208 Low level API        |
 *+----------------------------------+
 */
static int isl1208_i2c_read_regs(uint8_t regaddr, uint8_t *regs, uint8_t len)
{
    uint8_t        i;
    int            rv = 0;
    uint8_t        byte;
    uint8_t        ack;
    if( !regs || len<=0 )
    {
        rtc_print("ISL1208: Invalid input arguments\r\n");
        return -PARM_ERROR;
    }
    I2C_StartCondition(ISL1208_I2CBUS);
    if( NO_ERROR != (rv=I2C_SendAddress(ISL1208_I2CBUS, I2C_WR)) )
    {
        rtc_print("ISL1208: Send chipset address[W] failure: rv=0x%02x\r\n", rv);
        rv = -rv;
        goto OUT;
    }
    if( NO_ERROR != (rv=I2C_WriteByte(ISL1208_I2CBUS, regaddr) ) )
    {
        rtc_print("ISL1208: Set register[0x%02x] failure: rv=0x%02x\r\n", regaddr, rv);
        rv = -rv;
        goto OUT;
    }
    I2C_StartCondition(ISL1208_I2CBUS);
    if( NO_ERROR != (rv=I2C_SendAddress( ISL1208_I2CBUS, I2C_RD ) ) )
    {
        rtc_print("ISL1208: Send chipset address[W] failure: rv=0x%02x\r\n", rv);
        rv = -rv;
        goto OUT;
    }
    for (i=0; i<len; i++)
    {
         if( i == (len-1) )
             ack = ACK_NONE;
         else
             ack = ACK;
         rv = I2C_ReadByte(ISL1208_I2CBUS, &byte, ack, I2C_CLK_STRETCH_TIMEOUT);
         if( NO_ERROR != rv )
         {
             rtc_print("ISL1208: Read register data failure: rv=0x%02x\r\n", rv);
             rv = -rv;
             goto OUT;
         }
         regs[i] = byte;
    }
OUT:
    I2C_StopCondition(ISL1208_I2CBUS);
    return rv;
}
static int isl1208_i2c_write_regs(uint8_t regaddr, uint8_t *regs, uint8_t len)
{
    uint8_t        i;
    int            rv = 0;
    I2C_StartCondition(ISL1208_I2CBUS);
    if( NO_ERROR != (rv=I2C_SendAddress(ISL1208_I2CBUS, I2C_WR ) ) )
    {
        rtc_print("ISL1208: Send chipset address[W] failure: rv=0x%02x\r\n", rv);
        rv = -rv;
        goto OUT;
    }
    if( NO_ERROR != (rv=I2C_WriteByte(ISL1208_I2CBUS, regaddr) ) )
    {
        rtc_print("ISL1208: Set register[0x%02x] failure: rv=0x%02x\r\n", regaddr, rv);
        rv = -rv;
        goto OUT;
    }
    for (i=0; i<len; i++)
    {
        rv = I2C_WriteByte(ISL1208_I2CBUS, regs[i]);
        if( NO_ERROR != rv )
        {
            rtc_print("ISL1208: Write register data failure: rv=0x%02x\r\n", rv);
            rv = -rv;
            goto OUT;
        }
    }
    rv = 0;
OUT:
    I2C_StopCondition(ISL1208_I2CBUS);
    return rv;
}
#define bcd2bin(x)    (((x) & 0x0f) + ((x) >> 4) * 10)
#define bin2bcd(x)    ((((x) / 10) << 4) + (x) % 10)
int set_rtc_time(rtc_time_t tm)
{
    int                     rv;
    uint8_t                 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
    uint8_t                 sr;
    regs[ISL1208_REG_SC] = bin2bcd(tm.tm_sec);
    regs[ISL1208_REG_MN] = bin2bcd(tm.tm_min);
    regs[ISL1208_REG_HR] = bin2bcd(tm.tm_hour) | ISL1208_REG_HR_MIL;
    regs[ISL1208_REG_DT] = bin2bcd(tm.tm_mday);
    regs[ISL1208_REG_MO] = bin2bcd(tm.tm_mon);
    regs[ISL1208_REG_YR] = bin2bcd(tm.tm_year - 2000);
    //regs[ISL1208_REG_DW] = bin2bcd(tm.tm_wday & 7);
    if( i2c_init(ISL1208_I2CBUS, ISL1208_CHIPADDR) )
    {
        rtc_print("ISL1208: Initial I2C bus failure!\r\n");
        return -2;
    }
    rv = isl1208_i2c_read_regs(ISL1208_REG_SR, &sr, 1);
    if( rv < 0 )
    {
        rtc_print("ISL1208: read Status Register failure, rv=%d!\r\n", rv);
        rv = -3;
        goto OUT;
    }
    sr |= ISL1208_REG_SR_WRTC;
    rv = isl1208_i2c_write_regs(ISL1208_REG_SR, &sr, 1);
    if( rv < 0 )
    {
        rtc_print("ISL1208: Set Status Register WRTC failure, rv=%d!\r\n", rv);
        rv = -4;
        goto OUT;
    }
    rv=isl1208_i2c_write_regs(ISL1208_REG_SC, regs, ISL1208_RTC_SECTION_LEN);
    if(rv < 0 )
    {
        rtc_print("ISL1208: Set RTC section registeres failure, rv=%d!\r\n", rv);
        rv = -5;
        goto OUT;
    }
    sr &= (~ISL1208_REG_SR_WRTC);
    rv = isl1208_i2c_write_regs(ISL1208_REG_SR, &sr, 1);
    if( rv < 0 )
    {
        rtc_print("ISL1208: Clear Status Register WRTC failure, rv=%d!\r\n", rv);
        rv = -6;
        goto OUT;
    }
OUT:
    i2c_term(ISL1208_I2CBUS);
    return rv;
}
int get_rtc_time(rtc_time_t *tm)
{
    int                                    rv = 0;
    uint8_t                             regs[REGS_RTC_SR_LEN] = { 0, };
    if( !tm )
    {
        rtc_print("ISL1208: Invalid input arugments!\r\n");
        return -1;
    }
    if( i2c_init(ISL1208_I2CBUS, ISL1208_CHIPADDR) )
    {
        rtc_print("ISL1208: Initial I2C bus failure!\r\n");
        return -2;
    }
    rv = isl1208_i2c_read_regs(ISL1208_REG_SC, regs, REGS_RTC_SR_LEN);
    if (rv < 0)
    {
        rtc_print("ISL1208: read RTC_SECTION and SR registeres failure, rv=%d!\r\n", rv);
        rv = -3;
        goto OUT;
    }
    if( regs[ISL1208_REG_SR] & ISL1208_REG_SR_RTCF )
    {
        rtc_print("ISL1208: Initialize RTC time after power failure!\r\n");
        rv = -4;
        goto OUT;
    }
    tm->tm_sec = bcd2bin(regs[ISL1208_REG_SC]);
    tm->tm_min = bcd2bin(regs[ISL1208_REG_MN]);
    {
        const uint8_t _hr = regs[ISL1208_REG_HR];
        if (_hr & ISL1208_REG_HR_MIL)  /* 24H */
        {
            tm->tm_hour = bcd2bin(_hr & 0x3f);
        }
        else  /* 12H */
        {
            tm->tm_hour = bcd2bin(_hr & 0x1f);
            if (_hr & ISL1208_REG_HR_PM)
                tm->tm_hour += 12;
        }
    }
    tm->tm_mday = bcd2bin(regs[ISL1208_REG_DT]);
    tm->tm_mon  = bcd2bin(regs[ISL1208_REG_MO]);
    tm->tm_year = bcd2bin(regs[ISL1208_REG_YR]) + 2000;
    tm->tm_wday = bcd2bin(regs[ISL1208_REG_DW]);
OUT:
    i2c_term(ISL1208_I2CBUS);
    return rv;
}
void print_rtc_time(void)
{
    rtc_time_t tm;
    if( get_rtc_time(&tm) < 0 )
        return ;
    printf("%04d-%02d-%02d %02d:%02d:%02d %s\r\n", tm.tm_year, tm.tm_mon, tm.tm_mday,
        tm.tm_hour, tm.tm_min, tm.tm_sec, weekday[tm.tm_wday]);
}
Production/ISKBoard_QCTester/Core/Board/isl1208.h
New file
@@ -0,0 +1,37 @@
/*
 * isl1208.h
 *
 *  Created on: Jan 19, 2023
 *      Author: Wenxue
 */
#ifndef INC_ISL1208_H_
#define INC_ISL1208_H_
#include "i2c_bitbang.h"
#define ISL1208_I2CBUS           I2CBUS0   /* ISL1208 on GPIO I2C bus0 */
#define ISL1208_CHIPADDR         0x6F      /* ISL1208 7-Bits Chip address */
typedef struct rtc_time_s
{
    int       tm_sec;   /* [0 ~ 59/60 ]  */
    int       tm_min;   /* [0 ~ 59 ]     */
    int       tm_hour;  /* [0 ~ 23 ]     */
    int       tm_mday;  /* [1 ~ 31]      */
    int       tm_mon;   /* [1 ~ 12]      */
    int       tm_year;  /* [ 2000~2099 ] */
    int          tm_wday;  /* [0 ~ 6 ]      */
} rtc_time_t;
extern const char    *weekday[7];
extern int set_rtc_time(rtc_time_t tm);
extern int get_rtc_time(rtc_time_t *tm);
extern void print_rtc_time(void);
#endif /* INC_ISL1208_H_ */
Production/ISKBoard_QCTester/Core/Board/miscdev.c
New file
@@ -0,0 +1,172 @@
/*
 * miscdev.c
 *
 *  Created on: Jan 1, 2023
 *      Author: Think
 */
#include <miscdev.h>
#include "stm32l4xx_hal.h"
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "miscdev.h"
/*
 *+----------------------+
 *|     GPIO Led API     |
 *+----------------------+
 */
gpio_t     leds[LedMax] =
{
    { "RedLed",   LedRed_GPIO_Port,   LedRed_Pin},
    { "GreenLed", LedGreen_GPIO_Port, LedGreen_Pin},
    { "BlueLed",  LedBlue_GPIO_Port,  LedBlue_Pin},
};
void turn_led(lednum_t which, status_t status)
{
    GPIO_PinState        level;
    if( which >= LedMax )
        return ;
    level = status==OFF ? GPIO_PIN_SET : GPIO_PIN_RESET;
    HAL_GPIO_WritePin(leds[which].group, leds[which].pin, level);
}
void blink_led(lednum_t which, uint32_t interval)
{
    turn_led(which, ON);
    HAL_Delay(interval);
    turn_led(which, OFF);
    HAL_Delay(interval);
}
/*
 *+----------------------+
 *|    GPIO Relay API    |
 *+----------------------+
 */
void turn_relay(status_t status)
{
    GPIO_PinState        level;
    level = status==OFF ? GPIO_PIN_RESET : GPIO_PIN_SET;
    HAL_GPIO_WritePin(Relay_GPIO_Port, Relay_Pin, level);
}
/*
 *+----------------------+
 *|     GPIO Key API     |
 *+----------------------+
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    static unsigned char   status[3];
    if( Key1_Pin == GPIO_Pin )
    {
        status[0] ^= 1;
        turn_led(LedRed, status[0]);
    }
    else if( Key2_Pin == GPIO_Pin )
    {
        status[1] ^= 1;
        turn_led(LedGreen, status[1]);
    }
    if( Key3_Pin == GPIO_Pin )
    {
        status[2] ^= 1;
        turn_led(LedBlue, status[2]);
    }
}
/*
 *+----------------------------+
 *| ADC noisy & lux sensor API |
 *+----------------------------+
 */
int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy)
{
    uint8_t            i;
    uint32_t           timeout = 0xffffff;
    for(i=0; i<ADCCHN_MAX; i++)
    {
            HAL_ADC_Start(&hadc1);
            HAL_ADC_PollForConversion(&hadc1, timeout);
            if( ADCCHN_NOISY == i )
            {
                *noisy = HAL_ADC_GetValue(&hadc1);
            }
            else if( ADCCHN_LUX == i )
            {
                *lux = HAL_ADC_GetValue(&hadc1);
            }
            HAL_Delay(10);
    }
    HAL_ADC_Stop(&hadc1);
    return 0;
}
/*
 *+----------------------------+
 *  Timer Buzzer/delay API     |
 *+----------------------------+
 */
void beep_start(uint16_t times, uint16_t interval)
{
    while( times-- )
    {
        /* Start buzzer */
        if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4) != HAL_OK)
        {
            /* Starting Error */
            Error_Handler();
        }
        HAL_Delay(interval);
        /* Stop buzzer */
        if (HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_4) != HAL_OK)
        {
            /* Starting Error */
            Error_Handler();
        }
        HAL_Delay(interval);
    }
}
/* Max to 60000 us*/
void delay_us(uint16_t us)
{
    uint16_t differ = 60000-us;
    HAL_TIM_Base_Start(&htim6);
    __HAL_TIM_SET_COUNTER(&htim6, differ);
    while( differ < 60000 )
    {
        differ=__HAL_TIM_GET_COUNTER(&htim6);
    }
    HAL_TIM_Base_Stop(&htim6);
}
Production/ISKBoard_QCTester/Core/Board/miscdev.h
New file
@@ -0,0 +1,80 @@
/*
 * led.h
 *
 *  Created on: Jan 4, 2023
 *      Author: Think
 */
#ifndef INC_MISCDEV_H_
#define INC_MISCDEV_H_
#include "stm32l431xx.h"
typedef enum
{
    OFF,
    ON,
} status_t;
/*
 *+----------------------+
 *|     GPIO Led API     |
 *+----------------------+
 */
typedef enum
{
    LedRed,
    LedGreen,
    LedBlue,
    LedMax,
} lednum_t;
typedef struct gpio_s
{
    const char          *name;
    GPIO_TypeDef        *group;
    uint16_t             pin;
} gpio_t;
extern gpio_t     leds[LedMax] ;
extern void turn_led(lednum_t which, status_t status);
extern void blink_led(lednum_t which, uint32_t interval);
/*
 *+----------------------+
 *|    GPIO Relay API    |
 *+----------------------+
 */
extern void turn_relay(status_t status);
/*
 *+----------------------------+
 *| ADC noisy & lux sensor API |
 *+----------------------------+
 */
enum
{
    ADCCHN_NOISY,
    ADCCHN_LUX,
    ADCCHN_MAX,
};
extern int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy);
/*
 *+----------------------------+
 *  Timer Buzzer/delay API     |
 *+----------------------------+
 */
extern void beep_start(uint16_t times, uint16_t interval);
/* Max to 60000 us, DS18B20 driver depends on it */
extern void delay_us(uint16_t us);
#endif /* INC_LED_H_ */
Production/ISKBoard_QCTester/Core/Board/ringbuf.c
New file
@@ -0,0 +1,109 @@
/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    Based on ringbuffer.c by Patrick Prasse (patrick.prasse@gmx.net). Code
    has been modified by Telenor and Gemalto.
 */
#include <string.h>
#include <assert.h>
#include "ringbuf.h"
void rb_init (ring_buffer_t *rb, uint8_t *buf, int size)
{
    memset (rb, 0, sizeof (ring_buffer_t));
    rb->rd_pointer = 0;
    rb->wr_pointer = 0;
    rb->buffer= buf;
    memset(buf, 0, size);
    rb->size = size;
}
void rb_clear (ring_buffer_t *rb)
{
    memset(rb->buffer,0,rb->size);
    rb->rd_pointer=0;
    rb->wr_pointer=0;
}
int rb_data_size (ring_buffer_t *rb)
{
    return ((rb->wr_pointer - rb->rd_pointer) & (rb->size-1));
}
int rb_free_size (ring_buffer_t *rb)
{
    return (rb->size - 1 - rb_data_size(rb));
}
int rb_write (ring_buffer_t *rb, uint8_t *buf, int len)
{
    int total;
    int i;
    /* total = len = min(space, len) */
    total = rb_free_size(rb);
    if(len > total)
        len = total;
    else
        total = len;
    i = rb->wr_pointer;
    if(i + len > rb->size)
    {
        memcpy(rb->buffer + i, buf, rb->size - i);
        buf += rb->size - i;
        len -= rb->size - i;
        i = 0;
    }
    memcpy(rb->buffer + i, buf, len);
    rb->wr_pointer = i + len;
    return total;
}
int rb_read (ring_buffer_t *rb, uint8_t *buf, int max)
{
    int total;
    int i;
    /* total = len = min(used, len) */
    total = rb_data_size(rb);
    if(max > total)
        max = total;
    else
        total = max;
    i = rb->rd_pointer;
    if(i + max > rb->size)
    {
        memcpy(buf, rb->buffer + i, rb->size - i);
        buf += rb->size - i;
        max -= rb->size - i;
        i = 0;
    }
    memcpy(buf, rb->buffer + i, max);
    rb->rd_pointer = i + max;
    return total;
}
uint8_t rb_peek(ring_buffer_t *rb, int index)
{
    assert(index < rb_data_size(rb));
    return rb->buffer[((rb->rd_pointer + index) % rb->size)];
}
Production/ISKBoard_QCTester/Core/Board/ringbuf.h
New file
@@ -0,0 +1,58 @@
/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    Based on ringbuffer.h by Patrick Prasse (patrick.prasse@gmx.net). Code
    has been modified by Telenor and Gemalto.
 */
#ifndef __RINGBUF_H_
#define __RINGBUF_H_
#include <sys/types.h>
#include <stdint.h>
typedef struct ring_buffer_s {
    uint8_t *buffer;
    int wr_pointer;
    int rd_pointer;
    int size;
} ring_buffer_t;
/* Initial the ring buffer */
void rb_init (ring_buffer_t *ring, uint8_t *buf, int size) ;
/* Clear the ring buffer data  */
void rb_clear (ring_buffer_t *rb) ;
/* Get ring buffer left free size  */
int rb_free_size (ring_buffer_t *rb);
/* Get data size in the ring buffer  */
int rb_data_size (ring_buffer_t *rb);
/* Read $max bytes data from ring buffer $rb to $buf */
int rb_read (ring_buffer_t *rb, uint8_t *buf, int max);
/*  Description: Write $len bytes data in $buf into ring buffer $rb
 * Return Value: The actual written into ring buffer data size, if ring buffer
 * left space size small than $len, then only part of the data be written into.
 */
int rb_write (ring_buffer_t *rb, uint8_t *buf, int len) ;
/* Read a specify $index byte data in ring buffer $rb  */
uint8_t rb_peek(ring_buffer_t *rb, int index);
#endif /* __RINGBUF_H_ */
Production/ISKBoard_QCTester/Core/Board/sht20.c
New file
@@ -0,0 +1,211 @@
/*
 * sht20.c
 *
 *  Created on: Jan 19, 2023
 *      Author: Wenxue
 */
#include <sht20.h>
#include <stdio.h>
#include <string.h>
#define delay_ms(x)        HAL_Delay(x)
enum
{
    TRIG_T_MEASUREMENT_HM    = 0xE3, // command trig. temp meas. hold master
    TRIG_RH_MEASUREMENT_HM   = 0xE5, // command trig. humidity meas. hold master
    TRIG_T_MEASUREMENT_POLL  = 0xF3, // command trig. temp meas. no hold master
    TRIG_RH_MEASUREMENT_POLL = 0xF5, // command trig. humidity meas. no hold master
    USER_REG_W               = 0xE6, // command writing user register
    USER_REG_R               = 0xE7, // command reading user register
    SOFT_RESET               = 0xFE  // command soft reset
};
//#define CONFIG_SHT2X_DEBUG
#ifdef CONFIG_SHT2X_DEBUG
static inline void dump_buf(uint8_t *buf, uint32_t size)
{
    int      i;
    if(!buf)
        return ;
    for(i=0; i<size; i++)
        printf("%02x ", buf[i]);
    printf("\r\n");
}
#endif
#ifdef CONFIG_SHT2X_DEBUG
#define sht2x_print(format,args...) printf(format, ##args)
#else
#define sht2x_print(format,args...) do{} while(0);
#endif
static int sht2x_measure_value(uint8_t command, uint16_t *val);
static int sht2x_softreset(void);
uint32_t sht20_sample_TrH(uint32_t *temperature, uint32_t *humdity)
{
    uint16_t       sT;
    uint16_t       sRH;
    uint32_t       T;
    uint32_t       RH;
    uint32_t       TRH=TRH_FAIL_VAL;
    i2c_term(SHT2X_I2CBUS);
    if( i2c_init(SHT2X_I2CBUS, SHT2X_CHIPADDR) )
    {
        sht2x_print("SHT20 initial I2C bus failed.\r\n");
        return TRH;
    }
    if( sht2x_softreset() )
    {
        sht2x_print("SHT20 soft reset failed.\r\n");
        goto OUT;
    }
    sht2x_print("Start to measurement temperature...\r\n");
    if( sht2x_measure_value(TRIG_T_MEASUREMENT_POLL, &sT) < 0 )
    {
        sht2x_print("I2C measurement failed\r\n");
        goto OUT;
    }
    T=(uint32_t)(100*(float)((175.72*sT)/65536-46.85));
    sht2x_print("Measure temperature: %lu.%lu\r\n", T/100, T%100);
    if( temperature )
        *temperature=T;
    TRH = ((T/100)<<8|(T%100))<<16 | 0xFFFF;
    sht2x_print("Start to measurement relative humidity...\r\n");
    if( sht2x_measure_value(TRIG_RH_MEASUREMENT_POLL, &sRH) < 0 )
    {
        goto OUT;
    }
    RH=(uint32_t)(100*(float)((125*sRH)/65535-6.0));
    sht2x_print("Measure relative humidity: %lu.%lu%%\r\n", RH/100, RH%100);
    if( humdity )
        *humdity=RH;
    TRH &=  0xFFFF0000 | ((uint16_t)RH/100)<<8 | ((uint16_t)RH%100) ;
OUT:
    i2c_term(SHT2X_I2CBUS);
    return TRH;
}
int sht2x_softreset(void)
{
    uint8_t           command = SOFT_RESET;
    int               rv = 0;
    sht2x_print("Start soft reset sht2x\r\n");
    rv=i2c_write(SHT2X_I2CBUS, &command, 1);
    if( rv )
    {
        sht2x_print("SHT2X send soft reset command 0x%0x failure: rv=0x%02x\r\n", command, rv);
        return -rv;
    }
    delay_ms(15);
    return 0;
}
static int sht2x_checkcrc(uint8_t *data, uint8_t bytes, uint8_t checksum)
{
  uint8_t crc = 0;
  uint8_t i;
  uint8_t bit;
  //calculates 8-Bit checksum with given polynomial
  for (i=0; i<bytes; ++i)
  {
    crc ^= (data[i]);
    for (bit=8; bit>0; --bit)
    {
      if (crc & 0x80)
        crc = (crc << 1) ^ 0x0131; //POLYNOMIAL;
      else
        crc = (crc << 1);
    }
  }
  if (crc != checksum)
  {
    return -1;
  }
  else
  {
    return 0;
  }
}
static int sht2x_measure_value(uint8_t command, uint16_t *val)
{
    uint8_t        buf[3];    /* I2C������buffer */
    int            count=4;    /* �ܹ����Ĵ��� */
    if( !val )
    {
        sht2x_print("SHT2X invalid input arguments\r\n");
        return -1;
    }
    if(TRIG_T_MEASUREMENT_POLL!=command && TRIG_RH_MEASUREMENT_POLL !=command )
    {
        sht2x_print("SHT2X unsupport command: 0x%0x\r\n", command);
        return -2;
    }
    if( NO_ERROR != i2c_write(SHT2X_I2CBUS, &command, 1) )
    {
        sht2x_print("SHT2X send measure command 0x%0x failure\r\n", command);
        return -3;
    }
    if(TRIG_T_MEASUREMENT_POLL == command)
        delay_ms(85);
    else
        delay_ms(29);
    while(count--)
    {
        memset(buf, 0, 3);
        if( !i2c_read(SHT2X_I2CBUS, buf, 3) )
        {
            break;
        }
        delay_ms(5);
    }
    if( sht2x_checkcrc(buf, 2, buf[2])< 0 )
    {
#ifdef CONFIG_SHT2X_DEBUG
        sht2x_print("Measurement data checksum failure:\r\n");
        dump_buf(buf, 3);
#endif
        return -4;
    }
    if(TRIG_T_MEASUREMENT_POLL == command)
        *val = buf[0]<<8|(buf[1]&0xFC); //14bits(1111 1100)
    else
        *val = buf[0]<<8|(buf[1]&0xFF); //12bits(1100 0000)
    sht2x_print("Measurement temperature value: 0x%04x\r\n", *val);
  return 0;
}
Production/ISKBoard_QCTester/Core/Board/sht20.h
New file
@@ -0,0 +1,19 @@
/*
 * sht20.h
 *
 *  Created on: Jan 19, 2023
 *      Author: Wenxue
 */
#ifndef INC_SHT20_H_
#define INC_SHT20_H_
#include "i2c_bitbang.h"
#define SHT2X_I2CBUS           I2CBUS0   /* SHT20 on GPIO I2C bus0 */
#define SHT2X_CHIPADDR         0x40      /* SHT20 7-Bits Chip address */
#define TRH_FAIL_VAL      0xFFFFFFFF
extern uint32_t sht20_sample_TrH(uint32_t *temperature, uint32_t *humdity);
#endif /* INC_SHT20_H_ */
Production/ISKBoard_QCTester/Core/Board/w25q32.c
New file
@@ -0,0 +1,1025 @@
#include <stdio.h>
#include "w25q32.h"
#include "spi.h"
/*+------------------------------+
 *|     Debug print macro        |
 *+------------------------------+*/
#define CONFIG_W25Q_DEBUG
#ifdef  CONFIG_W25Q_DEBUG
#define w25q_print(format,args...) printf(format, ##args)
#else
#define w25q_print(format,args...) do{} while(0)
#endif
/*+------------------------------+
 *|   SPI Hardware definition    |
 *+------------------------------+*/
#define W25Q_SPI                   &hspi1
#define W25Q_CS_GPIO               SPI1_CS_GPIO_Port
#define W25Q_CS_PIN                SPI1_CS_Pin
#define DUMMY_BYTE                 0xFF
#define w25q_delay(delay)          HAL_Delay(delay)
#define w25q_cs_enable()           HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET)
#define w25q_cs_disable()          HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET)
/*+------------------------------+
 *|    W25Q Serial SPI Flash     |
 *+------------------------------+*/
/* Winbond -- w25x "page" are 256, "sectors" are 4KiB, "blocks" are 64K */
#define MB                  0x100000
#define W25Q_PGESIZE        256
#define W25Q_SECSIZE        4096
#define W25Q_BLKSIZE        65536
#define W25Q_NPGES(size)    ( ((size)*MB) / W25Q_PGESIZE )
#define W25Q_NSECS(size)    ( ((size)*MB) / W25Q_SECSIZE )
#define W25Q_NBLKS(size)    ( ((size)*MB) / W25Q_BLKSIZE )
#define INFO(_name, _jedecid, _npages, _nsectors, _nblocks) \
        .name       = _name, \
        .id         = _jedecid, \
        .pagesize   = W25Q_PGESIZE, \
        .npages     = _npages, \
        .sectorsize = W25Q_SECSIZE, \
        .nsectors   = _nsectors, \
        .blocksize  = W25Q_BLKSIZE, \
        .nblocks    = _nblocks,
#define ARRAY_SIZE(x)    (sizeof(x)/sizeof(x[0]))
flash_info_t w25q_ids[] =
{
    /* 1MB */
    { INFO("w25q80bl",  0xef4014, W25Q_NPGES(1), W25Q_NSECS(1), W25Q_NBLKS(1)) },
    { INFO("w25q80",    0xef5014, W25Q_NPGES(1), W25Q_NSECS(1), W25Q_NBLKS(1)) },
    /* 2MB */
    { INFO("w25q16cl",  0xef4015, W25Q_NPGES(2), W25Q_NSECS(2), W25Q_NBLKS(2)) },
    { INFO("w25q16dw",  0xef6015, W25Q_NPGES(2), W25Q_NSECS(2), W25Q_NBLKS(2)) },
    /* 4MB */
    { INFO("w25q32",    0xef4016, W25Q_NPGES(4), W25Q_NSECS(4), W25Q_NBLKS(4)) },
    { INFO("w25q32dw",  0xef6016, W25Q_NPGES(4), W25Q_NSECS(4), W25Q_NBLKS(4)) },
    { INFO("w25q32jv",  0xef7016, W25Q_NPGES(4), W25Q_NSECS(4), W25Q_NBLKS(4)) },
    { INFO("w25q32jwm", 0xef8016, W25Q_NPGES(4), W25Q_NSECS(4), W25Q_NBLKS(4)) },
    /* 8MB */
    { INFO("w25q64cv",  0xef4017, W25Q_NPGES(8), W25Q_NSECS(8), W25Q_NBLKS(8)) },
    { INFO("w25q64dw",  0xef6017, W25Q_NPGES(8), W25Q_NSECS(8), W25Q_NBLKS(8)) },
    { INFO("w25q64jv",  0xef7017, W25Q_NPGES(8), W25Q_NSECS(8), W25Q_NBLKS(8)) },
    /* 16MB */
    { INFO("w25q128",   0xef4018, W25Q_NPGES(16), W25Q_NSECS(16), W25Q_NBLKS(16)) },
    { INFO("w25q128fw", 0xef6018, W25Q_NPGES(16), W25Q_NSECS(16), W25Q_NBLKS(16)) },
    { INFO("w25q128jv", 0xef7018, W25Q_NPGES(16), W25Q_NSECS(16), W25Q_NBLKS(16)) },
    /* 32MB */
    { INFO("w25q256",   0xef4019, W25Q_NPGES(32), W25Q_NSECS(32), W25Q_NBLKS(32)) },
    { INFO("w25q256fw", 0xef6019, W25Q_NPGES(32), W25Q_NSECS(32), W25Q_NBLKS(32)) },
    { INFO("w25q256jw", 0xef7019, W25Q_NPGES(32), W25Q_NSECS(32), W25Q_NBLKS(32)) },
};
/*+------------------------------+
 *|   W25Q Serial Flash Driver   |
 *+------------------------------+*/
flash_info_t   *w25q;
static inline uint8_t w25q_spi_xfer(uint8_t txbyte)
{
    uint8_t rxbyte = 0x00;
    HAL_SPI_TransmitReceive(W25Q_SPI, &txbyte, &rxbyte, 1, 0xFFFF);
    return rxbyte;
}
void w25q_Reset(void)
{
    w25q_cs_enable();
    w25q_spi_xfer(0x66);  // enable reset
    w25q_spi_xfer(0x99);  // reset
    w25q_cs_disable();
}
uint16_t w25q_ReadID(void)
{
    uint16_t ID = 0x0;
    w25q_cs_enable();
    w25q_spi_xfer(0x90);
    w25q_spi_xfer(DUMMY_BYTE);
    w25q_spi_xfer(DUMMY_BYTE);
    w25q_spi_xfer(0x00);
    ID |= w25q_spi_xfer(DUMMY_BYTE)<<8; /* Manufacturer ID */
    ID |= w25q_spi_xfer(DUMMY_BYTE);    /* Device ID */
    w25q_cs_disable();
    return ID;
}
uint32_t w25q_ReadJedecID(void)
{
    uint32_t ID = 0x0;
    w25q_cs_enable();
    w25q_spi_xfer(0x9F);
    ID |= w25q_spi_xfer(DUMMY_BYTE)<<16; /* Manufacturer ID */
    ID |= w25q_spi_xfer(DUMMY_BYTE)<<8;  /* Device ID15~ID8 */
    ID |= w25q_spi_xfer(DUMMY_BYTE)<<0;  /* Device ID7~ID0  */
    w25q_cs_disable();
    return ID;
}
int w25q_Init(void)
{
    uint16_t    chipID;
    uint32_t    jedecID;
    int         i, found = 0;
    int         rv = 0;
    w25q_Reset();
    chipID = w25q_ReadID();
    if( 0x00 == chipID )
    {
        rv = -2;
        goto cleanup;
    }
    w25q_print("W25Q device ID: %04x\r\n", chipID);
    jedecID = w25q_ReadJedecID();
    if( 0x00 == jedecID )
    {
        rv = -3;
        goto cleanup;
    }
    w25q_print("W25Q JEDEC  ID: %lx\r\n", jedecID);
    for(i=0; i<ARRAY_SIZE(w25q_ids); i++)
    {
        if( w25q_ids[i].id == jedecID )
        {
            found = 1;
            w25q = &w25q_ids[i];
        }
    }
    rv = -4;
cleanup:
    if( found )
    {
        w25q_print("Dectec Norflash %s, Capacity %lu KB\r\n", w25q->name, w25q->blocksize*w25q->nblocks/1024);
        return 0;
    }
    w25q_print("ERROR: Can not found W25Q chipset by JDEDEC\r\n");
    return rv;
}
static inline void w25q_WriteEnable(void)
{
    w25q_cs_enable();
    w25q_spi_xfer(0x06);
    w25q_cs_disable();
}
static inline void w25q_WriteDisable(void)
{
    w25q_cs_enable();
    w25q_spi_xfer(0x04);
    w25q_cs_disable();
    w25q_delay(1);
}
static inline uint8_t w25q_ReadSR(int reg)
{
    uint8_t status = 0;
    w25q_cs_enable();
    if (REG_SR1 == reg)
    {
        w25q_spi_xfer(0x05);
        status = w25q_spi_xfer(DUMMY_BYTE);
    }
    else if (REG_SR2 == reg)
    {
        w25q_spi_xfer(0x35);
        status = w25q_spi_xfer(DUMMY_BYTE);
    }
    else if (REG_SR3 == reg)
    {
        w25q_spi_xfer(0x15);
        status = w25q_spi_xfer(DUMMY_BYTE);
    }
    w25q_cs_disable();
    return status;
}
static inline void w25q_WriteSR(int reg, uint8_t data)
{
    w25q_cs_enable();
    if (REG_SR1 == reg)
    {
        w25q_spi_xfer(0x01);
    }
    else if (REG_SR2 == reg)
    {
        w25q_spi_xfer(0x31);
    }
    else if (REG_SR2 == reg)
    {
        w25q_spi_xfer(0x11);
    }
    w25q_spi_xfer(data);
    w25q_cs_disable();
    return ;
}
/* Status Register[1] bit[0]: Erase/Write In Progress (BUSY) */
void w25q_Wait4Ready(void)
{
    uint8_t         regval;
    do
    {
        w25q_delay(1);
        regval = w25q_ReadSR(REG_SR1);
    } while ( !(regval&0x01) );
    return ;
}
void w25q_EraseChip(void)
{
    w25q_WriteEnable();
    w25q_cs_enable();
    w25q_spi_xfer(0xC7);
    w25q_cs_disable();
    w25q_Wait4Ready();
    w25q_print("chip erase %s done!\r\n", w25q->name);
    return ;
}
#if 0
//###################################################################################################################
void w25q_EraseChip(void)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
#if (_w25q_DEBUG == 1)
    uint32_t StartTime = HAL_GetTick();
    printf("w25q EraseChip Begin...\r\n");
#endif
    w25q_WriteEnable();
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    w25q_spi_xfer(0xC7);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
    w25q_WaitForWriteEnd();
#if (_w25q_DEBUG == 1)
    printf("w25q EraseBlock done after %d ms!\r\n", HAL_GetTick() - StartTime);
#endif
    w25q_delay(10);
    w25q.Lock = 0;
}
//###################################################################################################################
void w25q_EraseSector(uint32_t SectorAddr)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
#if (_w25q_DEBUG == 1)
    uint32_t StartTime = HAL_GetTick();
    printf("w25q EraseSector %d Begin...\r\n", SectorAddr);
#endif
    w25q_WaitForWriteEnd();
    SectorAddr = SectorAddr * w25q.SectorSize;
    w25q_WriteEnable();
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    if (w25q.ID >= W25Q256)
    {
        w25q_spi_xfer(0x21);
        w25q_spi_xfer((SectorAddr & 0xFF000000) >> 24);
    }
    else
    {
        w25q_spi_xfer(0x20);
    }
    w25q_spi_xfer((SectorAddr & 0xFF0000) >> 16);
    w25q_spi_xfer((SectorAddr & 0xFF00) >> 8);
    w25q_spi_xfer(SectorAddr & 0xFF);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
    w25q_WaitForWriteEnd();
#if (_w25q_DEBUG == 1)
    printf("w25q EraseSector done after %d ms\r\n", HAL_GetTick() - StartTime);
#endif
    w25q_delay(1);
    w25q.Lock = 0;
}
//###################################################################################################################
void w25q_EraseBlock(uint32_t BlockAddr)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
#if (_w25q_DEBUG == 1)
    printf("w25q EraseBlock %d Begin...\r\n", BlockAddr);
    w25q_delay(100);
    uint32_t StartTime = HAL_GetTick();
#endif
    w25q_WaitForWriteEnd();
    BlockAddr = BlockAddr * w25q.SectorSize * 16;
    w25q_WriteEnable();
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    if (w25q.ID >= W25Q256)
    {
        w25q_spi_xfer(0xDC);
        w25q_spi_xfer((BlockAddr & 0xFF000000) >> 24);
    }
    else
    {
        w25q_spi_xfer(0xD8);
    }
    w25q_spi_xfer((BlockAddr & 0xFF0000) >> 16);
    w25q_spi_xfer((BlockAddr & 0xFF00) >> 8);
    w25q_spi_xfer(BlockAddr & 0xFF);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
    w25q_WaitForWriteEnd();
#if (_w25q_DEBUG == 1)
    printf("w25q EraseBlock done after %d ms\r\n", HAL_GetTick() - StartTime);
    w25q_delay(100);
#endif
    w25q_delay(1);
    w25q.Lock = 0;
}
//###################################################################################################################
uint32_t w25q_PageToSector(uint32_t PageAddress)
{
    return ((PageAddress * w25q.PageSize) / w25q.SectorSize);
}
//###################################################################################################################
uint32_t w25q_PageToBlock(uint32_t PageAddress)
{
    return ((PageAddress * w25q.PageSize) / w25q.BlockSize);
}
//###################################################################################################################
uint32_t w25q_SectorToBlock(uint32_t SectorAddress)
{
    return ((SectorAddress * w25q.SectorSize) / w25q.BlockSize);
}
//###################################################################################################################
uint32_t w25q_SectorToPage(uint32_t SectorAddress)
{
    return (SectorAddress * w25q.SectorSize) / w25q.PageSize;
}
//###################################################################################################################
uint32_t w25q_BlockToPage(uint32_t BlockAddress)
{
    return (BlockAddress * w25q.BlockSize) / w25q.PageSize;
}
//###################################################################################################################
bool w25q_IsEmptyPage(uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_PageSize)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
    if (((NumByteToCheck_up_to_PageSize + OffsetInByte) > w25q.PageSize) || (NumByteToCheck_up_to_PageSize == 0))
        NumByteToCheck_up_to_PageSize = w25q.PageSize - OffsetInByte;
#if (_w25q_DEBUG == 1)
    printf("w25q CheckPage:%d, Offset:%d, Bytes:%d begin...\r\n", Page_Address, OffsetInByte, NumByteToCheck_up_to_PageSize);
    w25q_delay(100);
    uint32_t StartTime = HAL_GetTick();
#endif
    uint8_t pBuffer[32];
    uint32_t WorkAddress;
    uint32_t i;
    for (i = OffsetInByte; i < w25q.PageSize; i += sizeof(pBuffer))
    {
        HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
        WorkAddress = (i + Page_Address * w25q.PageSize);
        if (w25q.ID >= W25Q256)
        {
            w25q_spi_xfer(0x0C);
            w25q_spi_xfer((WorkAddress & 0xFF000000) >> 24);
        }
        else
        {
            w25q_spi_xfer(0x0B);
        }
        w25q_spi_xfer((WorkAddress & 0xFF0000) >> 16);
        w25q_spi_xfer((WorkAddress & 0xFF00) >> 8);
        w25q_spi_xfer(WorkAddress & 0xFF);
        w25q_spi_xfer(0);
        HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, sizeof(pBuffer), 100);
        HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
        for (uint8_t x = 0; x < sizeof(pBuffer); x++)
        {
            if (pBuffer[x] != 0xFF)
                goto NOT_EMPTY;
        }
    }
    if ((w25q.PageSize + OffsetInByte) % sizeof(pBuffer) != 0)
    {
        i -= sizeof(pBuffer);
        for (; i < w25q.PageSize; i++)
        {
            HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
            WorkAddress = (i + Page_Address * w25q.PageSize);
            w25q_spi_xfer(0x0B);
            if (w25q.ID >= W25Q256)
            {
                w25q_spi_xfer(0x0C);
                w25q_spi_xfer((WorkAddress & 0xFF000000) >> 24);
            }
            else
            {
                w25q_spi_xfer(0x0B);
            }
            w25q_spi_xfer((WorkAddress & 0xFF0000) >> 16);
            w25q_spi_xfer((WorkAddress & 0xFF00) >> 8);
            w25q_spi_xfer(WorkAddress & 0xFF);
            w25q_spi_xfer(0);
            HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, 1, 100);
            HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
            if (pBuffer[0] != 0xFF)
                goto NOT_EMPTY;
        }
    }
#if (_w25q_DEBUG == 1)
    printf("w25q CheckPage is Empty in %d ms\r\n", HAL_GetTick() - StartTime);
    w25q_delay(100);
#endif
    w25q.Lock = 0;
    return true;
NOT_EMPTY:
#if (_w25q_DEBUG == 1)
    printf("w25q CheckPage is Not Empty in %d ms\r\n", HAL_GetTick() - StartTime);
    w25q_delay(100);
#endif
    w25q.Lock = 0;
    return false;
}
//###################################################################################################################
bool w25q_IsEmptySector(uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_SectorSize)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
    if ((NumByteToCheck_up_to_SectorSize > w25q.SectorSize) || (NumByteToCheck_up_to_SectorSize == 0))
        NumByteToCheck_up_to_SectorSize = w25q.SectorSize;
#if (_w25q_DEBUG == 1)
    printf("w25q CheckSector:%d, Offset:%d, Bytes:%d begin...\r\n", Sector_Address, OffsetInByte, NumByteToCheck_up_to_SectorSize);
    w25q_delay(100);
    uint32_t StartTime = HAL_GetTick();
#endif
    uint8_t pBuffer[32];
    uint32_t WorkAddress;
    uint32_t i;
    for (i = OffsetInByte; i < w25q.SectorSize; i += sizeof(pBuffer))
    {
        HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
        WorkAddress = (i + Sector_Address * w25q.SectorSize);
        if (w25q.ID >= W25Q256)
        {
            w25q_spi_xfer(0x0C);
            w25q_spi_xfer((WorkAddress & 0xFF000000) >> 24);
        }
        else
        {
            w25q_spi_xfer(0x0B);
        }
        w25q_spi_xfer((WorkAddress & 0xFF0000) >> 16);
        w25q_spi_xfer((WorkAddress & 0xFF00) >> 8);
        w25q_spi_xfer(WorkAddress & 0xFF);
        w25q_spi_xfer(0);
        HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, sizeof(pBuffer), 100);
        HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
        for (uint8_t x = 0; x < sizeof(pBuffer); x++)
        {
            if (pBuffer[x] != 0xFF)
                goto NOT_EMPTY;
        }
    }
    if ((w25q.SectorSize + OffsetInByte) % sizeof(pBuffer) != 0)
    {
        i -= sizeof(pBuffer);
        for (; i < w25q.SectorSize; i++)
        {
            HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
            WorkAddress = (i + Sector_Address * w25q.SectorSize);
            if (w25q.ID >= W25Q256)
            {
                w25q_spi_xfer(0x0C);
                w25q_spi_xfer((WorkAddress & 0xFF000000) >> 24);
            }
            else
            {
                w25q_spi_xfer(0x0B);
            }
            w25q_spi_xfer((WorkAddress & 0xFF0000) >> 16);
            w25q_spi_xfer((WorkAddress & 0xFF00) >> 8);
            w25q_spi_xfer(WorkAddress & 0xFF);
            w25q_spi_xfer(0);
            HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, 1, 100);
            HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
            if (pBuffer[0] != 0xFF)
                goto NOT_EMPTY;
        }
    }
#if (_w25q_DEBUG == 1)
    printf("w25q CheckSector is Empty in %d ms\r\n", HAL_GetTick() - StartTime);
    w25q_delay(100);
#endif
    w25q.Lock = 0;
    return true;
NOT_EMPTY:
#if (_w25q_DEBUG == 1)
    printf("w25q CheckSector is Not Empty in %d ms\r\n", HAL_GetTick() - StartTime);
    w25q_delay(100);
#endif
    w25q.Lock = 0;
    return false;
}
//###################################################################################################################
bool w25q_IsEmptyBlock(uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_BlockSize)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
    if ((NumByteToCheck_up_to_BlockSize > w25q.BlockSize) || (NumByteToCheck_up_to_BlockSize == 0))
        NumByteToCheck_up_to_BlockSize = w25q.BlockSize;
#if (_w25q_DEBUG == 1)
    printf("w25q CheckBlock:%d, Offset:%d, Bytes:%d begin...\r\n", Block_Address, OffsetInByte, NumByteToCheck_up_to_BlockSize);
    w25q_delay(100);
    uint32_t StartTime = HAL_GetTick();
#endif
    uint8_t pBuffer[32];
    uint32_t WorkAddress;
    uint32_t i;
    for (i = OffsetInByte; i < w25q.BlockSize; i += sizeof(pBuffer))
    {
        HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
        WorkAddress = (i + Block_Address * w25q.BlockSize);
        if (w25q.ID >= W25Q256)
        {
            w25q_spi_xfer(0x0C);
            w25q_spi_xfer((WorkAddress & 0xFF000000) >> 24);
        }
        else
        {
            w25q_spi_xfer(0x0B);
        }
        w25q_spi_xfer((WorkAddress & 0xFF0000) >> 16);
        w25q_spi_xfer((WorkAddress & 0xFF00) >> 8);
        w25q_spi_xfer(WorkAddress & 0xFF);
        w25q_spi_xfer(0);
        HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, sizeof(pBuffer), 100);
        HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
        for (uint8_t x = 0; x < sizeof(pBuffer); x++)
        {
            if (pBuffer[x] != 0xFF)
                goto NOT_EMPTY;
        }
    }
    if ((w25q.BlockSize + OffsetInByte) % sizeof(pBuffer) != 0)
    {
        i -= sizeof(pBuffer);
        for (; i < w25q.BlockSize; i++)
        {
            HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
            WorkAddress = (i + Block_Address * w25q.BlockSize);
            if (w25q.ID >= W25Q256)
            {
                w25q_spi_xfer(0x0C);
                w25q_spi_xfer((WorkAddress & 0xFF000000) >> 24);
            }
            else
            {
                w25q_spi_xfer(0x0B);
            }
            w25q_spi_xfer((WorkAddress & 0xFF0000) >> 16);
            w25q_spi_xfer((WorkAddress & 0xFF00) >> 8);
            w25q_spi_xfer(WorkAddress & 0xFF);
            w25q_spi_xfer(0);
            HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, 1, 100);
            HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
            if (pBuffer[0] != 0xFF)
                goto NOT_EMPTY;
        }
    }
#if (_w25q_DEBUG == 1)
    printf("w25q CheckBlock is Empty in %d ms\r\n", HAL_GetTick() - StartTime);
    w25q_delay(100);
#endif
    w25q.Lock = 0;
    return true;
NOT_EMPTY:
#if (_w25q_DEBUG == 1)
    printf("w25q CheckBlock is Not Empty in %d ms\r\n", HAL_GetTick() - StartTime);
    w25q_delay(100);
#endif
    w25q.Lock = 0;
    return false;
}
//###################################################################################################################
void w25q_WriteByte(uint8_t pBuffer, uint32_t WriteAddr_inBytes)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
#if (_w25q_DEBUG == 1)
    uint32_t StartTime = HAL_GetTick();
    printf("w25q WriteByte 0x%02X at address %d begin...", pBuffer, WriteAddr_inBytes);
#endif
    w25q_WaitForWriteEnd();
    w25q_WriteEnable();
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    if (w25q.ID >= W25Q256)
    {
        w25q_spi_xfer(0x12);
        w25q_spi_xfer((WriteAddr_inBytes & 0xFF000000) >> 24);
    }
    else
    {
        w25q_spi_xfer(0x02);
    }
    w25q_spi_xfer((WriteAddr_inBytes & 0xFF0000) >> 16);
    w25q_spi_xfer((WriteAddr_inBytes & 0xFF00) >> 8);
    w25q_spi_xfer(WriteAddr_inBytes & 0xFF);
    w25q_spi_xfer(pBuffer);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
    w25q_WaitForWriteEnd();
#if (_w25q_DEBUG == 1)
    printf("w25q WriteByte done after %d ms\r\n", HAL_GetTick() - StartTime);
#endif
    w25q.Lock = 0;
}
//###################################################################################################################
void w25q_WritePage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_PageSize)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
    if (((NumByteToWrite_up_to_PageSize + OffsetInByte) > w25q.PageSize) || (NumByteToWrite_up_to_PageSize == 0))
        NumByteToWrite_up_to_PageSize = w25q.PageSize - OffsetInByte;
    if ((OffsetInByte + NumByteToWrite_up_to_PageSize) > w25q.PageSize)
        NumByteToWrite_up_to_PageSize = w25q.PageSize - OffsetInByte;
#if (_w25q_DEBUG == 1)
    printf("w25q WritePage:%d, Offset:%d ,Writes %d Bytes, begin...\r\n", Page_Address, OffsetInByte, NumByteToWrite_up_to_PageSize);
    w25q_delay(100);
    uint32_t StartTime = HAL_GetTick();
#endif
    w25q_WaitForWriteEnd();
    w25q_WriteEnable();
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    Page_Address = (Page_Address * w25q.PageSize) + OffsetInByte;
    if (w25q.ID >= W25Q256)
    {
        w25q_spi_xfer(0x12);
        w25q_spi_xfer((Page_Address & 0xFF000000) >> 24);
    }
    else
    {
        w25q_spi_xfer(0x02);
    }
    w25q_spi_xfer((Page_Address & 0xFF0000) >> 16);
    w25q_spi_xfer((Page_Address & 0xFF00) >> 8);
    w25q_spi_xfer(Page_Address & 0xFF);
    HAL_SPI_Transmit(&_W25q_spi_xfer, pBuffer, NumByteToWrite_up_to_PageSize, 100);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
    w25q_WaitForWriteEnd();
#if (_w25q_DEBUG == 1)
    StartTime = HAL_GetTick() - StartTime;
    for (uint32_t i = 0; i < NumByteToWrite_up_to_PageSize; i++)
    {
        if ((i % 8 == 0) && (i > 2))
        {
            printf("\r\n");
            w25q_delay(10);
        }
        printf("0x%02X,", pBuffer[i]);
    }
    printf("\r\n");
    printf("w25q WritePage done after %d ms\r\n", StartTime);
    w25q_delay(100);
#endif
    w25q_delay(1);
    w25q.Lock = 0;
}
//###################################################################################################################
void w25q_WriteSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_SectorSize)
{
    if ((NumByteToWrite_up_to_SectorSize > w25q.SectorSize) || (NumByteToWrite_up_to_SectorSize == 0))
        NumByteToWrite_up_to_SectorSize = w25q.SectorSize;
#if (_w25q_DEBUG == 1)
    printf("+++w25q WriteSector:%d, Offset:%d ,Write %d Bytes, begin...\r\n", Sector_Address, OffsetInByte, NumByteToWrite_up_to_SectorSize);
    w25q_delay(100);
#endif
    if (OffsetInByte >= w25q.SectorSize)
    {
#if (_w25q_DEBUG == 1)
        printf("---w25q WriteSector Faild!\r\n");
        w25q_delay(100);
#endif
        return;
    }
    uint32_t StartPage;
    int32_t BytesToWrite;
    uint32_t LocalOffset;
    if ((OffsetInByte + NumByteToWrite_up_to_SectorSize) > w25q.SectorSize)
        BytesToWrite = w25q.SectorSize - OffsetInByte;
    else
        BytesToWrite = NumByteToWrite_up_to_SectorSize;
    StartPage = w25q_SectorToPage(Sector_Address) + (OffsetInByte / w25q.PageSize);
    LocalOffset = OffsetInByte % w25q.PageSize;
    do
    {
        w25q_WritePage(pBuffer, StartPage, LocalOffset, BytesToWrite);
        StartPage++;
        BytesToWrite -= w25q.PageSize - LocalOffset;
        pBuffer += w25q.PageSize - LocalOffset;
        LocalOffset = 0;
    } while (BytesToWrite > 0);
#if (_w25q_DEBUG == 1)
    printf("---w25q WriteSector Done\r\n");
    w25q_delay(100);
#endif
}
//###################################################################################################################
void w25q_WriteBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_BlockSize)
{
    if ((NumByteToWrite_up_to_BlockSize > w25q.BlockSize) || (NumByteToWrite_up_to_BlockSize == 0))
        NumByteToWrite_up_to_BlockSize = w25q.BlockSize;
#if (_w25q_DEBUG == 1)
    printf("+++w25q WriteBlock:%d, Offset:%d ,Write %d Bytes, begin...\r\n", Block_Address, OffsetInByte, NumByteToWrite_up_to_BlockSize);
    w25q_delay(100);
#endif
    if (OffsetInByte >= w25q.BlockSize)
    {
#if (_w25q_DEBUG == 1)
        printf("---w25q WriteBlock Faild!\r\n");
        w25q_delay(100);
#endif
        return;
    }
    uint32_t StartPage;
    int32_t BytesToWrite;
    uint32_t LocalOffset;
    if ((OffsetInByte + NumByteToWrite_up_to_BlockSize) > w25q.BlockSize)
        BytesToWrite = w25q.BlockSize - OffsetInByte;
    else
        BytesToWrite = NumByteToWrite_up_to_BlockSize;
    StartPage = w25q_BlockToPage(Block_Address) + (OffsetInByte / w25q.PageSize);
    LocalOffset = OffsetInByte % w25q.PageSize;
    do
    {
        w25q_WritePage(pBuffer, StartPage, LocalOffset, BytesToWrite);
        StartPage++;
        BytesToWrite -= w25q.PageSize - LocalOffset;
        pBuffer += w25q.PageSize - LocalOffset;
        LocalOffset = 0;
    } while (BytesToWrite > 0);
#if (_w25q_DEBUG == 1)
    printf("---w25q WriteBlock Done\r\n");
    w25q_delay(100);
#endif
}
//###################################################################################################################
void w25q_ReadByte(uint8_t *pBuffer, uint32_t Bytes_Address)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
#if (_w25q_DEBUG == 1)
    uint32_t StartTime = HAL_GetTick();
    printf("w25q ReadByte at address %d begin...\r\n", Bytes_Address);
#endif
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    if (w25q.ID >= W25Q256)
    {
        w25q_spi_xfer(0x0C);
        w25q_spi_xfer((Bytes_Address & 0xFF000000) >> 24);
    }
    else
    {
        w25q_spi_xfer(0x0B);
    }
    w25q_spi_xfer((Bytes_Address & 0xFF0000) >> 16);
    w25q_spi_xfer((Bytes_Address & 0xFF00) >> 8);
    w25q_spi_xfer(Bytes_Address & 0xFF);
    w25q_spi_xfer(0);
    *pBuffer = w25q_spi_xfer(DUMMY_BYTE);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
#if (_w25q_DEBUG == 1)
    printf("w25q ReadByte 0x%02X done after %d ms\r\n", *pBuffer, HAL_GetTick() - StartTime);
#endif
    w25q.Lock = 0;
}
//###################################################################################################################
void w25q_ReadBytes(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
#if (_w25q_DEBUG == 1)
    uint32_t StartTime = HAL_GetTick();
    printf("w25q ReadBytes at Address:%d, %d Bytes  begin...\r\n", ReadAddr, NumByteToRead);
#endif
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    if (w25q.ID >= W25Q256)
    {
        w25q_spi_xfer(0x0C);
        w25q_spi_xfer((ReadAddr & 0xFF000000) >> 24);
    }
    else
    {
        w25q_spi_xfer(0x0B);
    }
    w25q_spi_xfer((ReadAddr & 0xFF0000) >> 16);
    w25q_spi_xfer((ReadAddr & 0xFF00) >> 8);
    w25q_spi_xfer(ReadAddr & 0xFF);
    w25q_spi_xfer(0);
    HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, NumByteToRead, 2000);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
#if (_w25q_DEBUG == 1)
    StartTime = HAL_GetTick() - StartTime;
    for (uint32_t i = 0; i < NumByteToRead; i++)
    {
        if ((i % 8 == 0) && (i > 2))
        {
            printf("\r\n");
            w25q_delay(10);
        }
        printf("0x%02X,", pBuffer[i]);
    }
    printf("\r\n");
    printf("w25q ReadBytes done after %d ms\r\n", StartTime);
    w25q_delay(100);
#endif
    w25q_delay(1);
    w25q.Lock = 0;
}
//###################################################################################################################
void w25q_ReadPage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_PageSize)
{
    while (w25q.Lock == 1)
        w25q_delay(1);
    w25q.Lock = 1;
    if ((NumByteToRead_up_to_PageSize > w25q.PageSize) || (NumByteToRead_up_to_PageSize == 0))
        NumByteToRead_up_to_PageSize = w25q.PageSize;
    if ((OffsetInByte + NumByteToRead_up_to_PageSize) > w25q.PageSize)
        NumByteToRead_up_to_PageSize = w25q.PageSize - OffsetInByte;
#if (_w25q_DEBUG == 1)
    printf("w25q ReadPage:%d, Offset:%d ,Read %d Bytes, begin...\r\n", Page_Address, OffsetInByte, NumByteToRead_up_to_PageSize);
    w25q_delay(100);
    uint32_t StartTime = HAL_GetTick();
#endif
    Page_Address = Page_Address * w25q.PageSize + OffsetInByte;
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_RESET);
    if (w25q.ID >= W25Q256)
    {
        w25q_spi_xfer(0x0C);
        w25q_spi_xfer((Page_Address & 0xFF000000) >> 24);
    }
    else
    {
        w25q_spi_xfer(0x0B);
    }
    w25q_spi_xfer((Page_Address & 0xFF0000) >> 16);
    w25q_spi_xfer((Page_Address & 0xFF00) >> 8);
    w25q_spi_xfer(Page_Address & 0xFF);
    w25q_spi_xfer(0);
    HAL_SPI_Receive(&_W25q_spi_xfer, pBuffer, NumByteToRead_up_to_PageSize, 100);
    HAL_GPIO_WritePin(W25Q_CS_GPIO, W25Q_CS_PIN, GPIO_PIN_SET);
#if (_w25q_DEBUG == 1)
    StartTime = HAL_GetTick() - StartTime;
    for (uint32_t i = 0; i < NumByteToRead_up_to_PageSize; i++)
    {
        if ((i % 8 == 0) && (i > 2))
        {
            printf("\r\n");
            w25q_delay(10);
        }
        printf("0x%02X,", pBuffer[i]);
    }
    printf("\r\n");
    printf("w25q ReadPage done after %d ms\r\n", StartTime);
    w25q_delay(100);
#endif
    w25q_delay(1);
    w25q.Lock = 0;
}
//###################################################################################################################
void w25q_ReadSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_SectorSize)
{
    if ((NumByteToRead_up_to_SectorSize > w25q.SectorSize) || (NumByteToRead_up_to_SectorSize == 0))
        NumByteToRead_up_to_SectorSize = w25q.SectorSize;
#if (_w25q_DEBUG == 1)
    printf("+++w25q ReadSector:%d, Offset:%d ,Read %d Bytes, begin...\r\n", Sector_Address, OffsetInByte, NumByteToRead_up_to_SectorSize);
    w25q_delay(100);
#endif
    if (OffsetInByte >= w25q.SectorSize)
    {
#if (_w25q_DEBUG == 1)
        printf("---w25q ReadSector Faild!\r\n");
        w25q_delay(100);
#endif
        return;
    }
    uint32_t StartPage;
    int32_t BytesToRead;
    uint32_t LocalOffset;
    if ((OffsetInByte + NumByteToRead_up_to_SectorSize) > w25q.SectorSize)
        BytesToRead = w25q.SectorSize - OffsetInByte;
    else
        BytesToRead = NumByteToRead_up_to_SectorSize;
    StartPage = w25q_SectorToPage(Sector_Address) + (OffsetInByte / w25q.PageSize);
    LocalOffset = OffsetInByte % w25q.PageSize;
    do
    {
        w25q_ReadPage(pBuffer, StartPage, LocalOffset, BytesToRead);
        StartPage++;
        BytesToRead -= w25q.PageSize - LocalOffset;
        pBuffer += w25q.PageSize - LocalOffset;
        LocalOffset = 0;
    } while (BytesToRead > 0);
#if (_w25q_DEBUG == 1)
    printf("---w25q ReadSector Done\r\n");
    w25q_delay(100);
#endif
}
//###################################################################################################################
void w25q_ReadBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_BlockSize)
{
    if ((NumByteToRead_up_to_BlockSize > w25q.BlockSize) || (NumByteToRead_up_to_BlockSize == 0))
        NumByteToRead_up_to_BlockSize = w25q.BlockSize;
#if (_w25q_DEBUG == 1)
    printf("+++w25q ReadBlock:%d, Offset:%d ,Read %d Bytes, begin...\r\n", Block_Address, OffsetInByte, NumByteToRead_up_to_BlockSize);
    w25q_delay(100);
#endif
    if (OffsetInByte >= w25q.BlockSize)
    {
#if (_w25q_DEBUG == 1)
        printf("w25q ReadBlock Faild!\r\n");
        w25q_delay(100);
#endif
        return;
    }
    uint32_t StartPage;
    int32_t BytesToRead;
    uint32_t LocalOffset;
    if ((OffsetInByte + NumByteToRead_up_to_BlockSize) > w25q.BlockSize)
        BytesToRead = w25q.BlockSize - OffsetInByte;
    else
        BytesToRead = NumByteToRead_up_to_BlockSize;
    StartPage = w25q_BlockToPage(Block_Address) + (OffsetInByte / w25q.PageSize);
    LocalOffset = OffsetInByte % w25q.PageSize;
    do
    {
        w25q_ReadPage(pBuffer, StartPage, LocalOffset, BytesToRead);
        StartPage++;
        BytesToRead -= w25q.PageSize - LocalOffset;
        pBuffer += w25q.PageSize - LocalOffset;
        LocalOffset = 0;
    } while (BytesToRead > 0);
#if (_w25q_DEBUG == 1)
    printf("---w25q ReadBlock Done\r\n");
    w25q_delay(100);
#endif
}
#endif
Production/ISKBoard_QCTester/Core/Board/w25q32.h
New file
@@ -0,0 +1,60 @@
#ifndef _w25Q32_H
#define _W25Q32_H
#include "stm32l4xx_hal.h"
typedef enum
{
    W25Q80,
    W25Q16,
    W25Q32,
} w25q_chip_t;
typedef enum
{
    REG_SR1=1,
    REG_SR2,
    REG_SR3,
} w25q_sreg_t;
typedef struct flash_info_s
{
    char        *name;       /* Chip name */
    uint32_t     id;         /* JEDEC ID  */
    uint32_t     pagesize;   /* page size */
    uint32_t     npages;     /* page count */
    uint32_t     sectorsize; /* sector size */
    uint32_t     nsectors;   /* sector count */
    uint32_t     blocksize;  /* block size */
    uint32_t     nblocks;    /* block count */
} flash_info_t;
extern flash_info_t   *w25q;
int w25q_Init(void);
void w25q_EraseChip(void);
void w25q_EraseSector(uint32_t SectorAddr);
void w25q_EraseBlock(uint32_t BlockAddr);
uint32_t w25q_PageToSector(uint32_t PageAddress);
uint32_t w25q_PageToBlock(uint32_t PageAddress);
uint32_t w25q_SectorToBlock(uint32_t SectorAddress);
uint32_t w25q_SectorToPage(uint32_t SectorAddress);
uint32_t w25q_BlockToPage(uint32_t BlockAddress);
int w25q_IsEmptyPage(uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_PageSize);
int w25q_IsEmptySector(uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_SectorSize);
int w25q_IsEmptyBlock(uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_BlockSize);
void w25q_WriteByte(uint8_t pBuffer, uint32_t Bytes_Address);
void w25q_WritePage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_PageSize);
void w25q_WriteSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_SectorSize);
void w25q_WriteBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_BlockSize);
void w25q_ReadByte(uint8_t *pBuffer, uint32_t Bytes_Address);
void w25q_ReadBytes(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead);
void w25q_ReadPage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_PageSize);
void w25q_ReadSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_SectorSize);
void w25q_ReadBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_BlockSize);
#endif
Production/ISKBoard_QCTester/Core/Board/ws2812b.c
New file
@@ -0,0 +1,169 @@
/* Reference: https://blog.csdn.net/Lennon8_8/article/details/108980808
 * ws2812b.c
 *
 *  Created on: 2023年2月13日
 *      Author: Think
 */
#include <string.h>
#include <stdint.h>
#include "ws2812b.h"
#include "miscdev.h"
static color_t g_ColorPanel[WS2812_NUM];
typedef struct ws_gpio_s
{
    GPIO_TypeDef        *group;
    uint16_t             pin;
} ws_gpio_t;
static ws_gpio_t   ws_gpio =  /* IO pin connected to PC2 */
{
        .group = GPIOC,
        .pin   = GPIO_PIN_2,
};
#define ws_setpin(x) if(!x) ws_gpio.group->BRR=ws_gpio.pin; else ws_gpio.group->BSRR=ws_gpio.pin
/*
 * 1 NOP = 1/80MHz = 12.5ns => 100ns = 8 * NOP
 *
 * */
#define delay_200ns() { __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); \
                        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); }
void ws2812b_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = ws_gpio.pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(ws_gpio.group, &GPIO_InitStruct);
    ws2812b_reset();
    return ;
}
static inline void ws2812b_WriteByte(uint8_t byte)
{
    int      i;
    for(i=0; i<8; i++)
    {
        if(byte & 0x80)
        {
            /* Sequence Send 1: T1H: 580ns~1.6us  T1L: 200ns~420ns:
             *
             * +--------------+         +
             * |<-   T1H    ->|<- T1L ->|
             * |              +---------+
             */
            ws_setpin(1); // T1H
            delay_us(1);
            ws_setpin(0); // T1L
            delay_200ns(); //200ns test okay
        }
        else
        {
            /* Sequence Send 0: T0H: 220ns~380ns  T0L: 580ns~1.6ns:
             *
             * +---------+              +
             * |<- T0H ->|<-    T0L   ->|
             * |         +--------------+
             */
            ws_setpin(1);  // T0H
            delay_200ns(); //200ns test okay
            ws_setpin(0); // T0L
            delay_us(1);
        }
        byte<<=1;
    }
    return ;
}
void ws2812b_reset(void)
{
    /* Sequence Reset: Treset >280us:
     *
     * +              +
     * |<-  Treset  ->|
     * +--------------+
     */
    ws_setpin(0);
    delay_us(300);
    memset(g_ColorPanel, 0, sizeof(g_ColorPanel));
    return ;
}
static inline void ws2812b_SendColor(color_t color)
{
    ws2812b_WriteByte(color.pixel.green);
    ws2812b_WriteByte(color.pixel.red);
    ws2812b_WriteByte(color.pixel.blue);
    return ;
}
static inline void ws2812b_Refresh(void)
{
    int      i;
    for(i=0; i<WS2812_NUM; i++)
    {
        ws2812b_SendColor(g_ColorPanel[i]);
    }
    return ;
}
static inline int ws2812b_SetPixel(int which, color_t color)
{
    if( which<0 || which>=WS2812_NUM )
        return -1;
    g_ColorPanel[which].pixel.red   = color.pixel.red;
    g_ColorPanel[which].pixel.green = color.pixel.green;
    g_ColorPanel[which].pixel.blue  = color.pixel.blue;
    return 0;
}
int ws2812b_turn(int which, color_t color)
{
    if( which<0 || which>=WS2812_NUM )
        return -1;
    ws2812b_SetPixel(which, color);
    ws2812b_Refresh();
    return 0;
}
void ws2812b_blink(void)
{
    int      c, i;
    color_t  colors[4] = {[0].data=PIXEL_B, [1].data=PIXEL_R, [2].data=PIXEL_G, [3].data=PIXEL_W};
    color_t  color_off = {.data = PIXEL_OFF};
    for(c=0; c<4; c++) /* color */
    {
        for(i=0; i<WS2812_NUM; i++)
        {
            ws2812b_turn(i, colors[c]);
            HAL_Delay(200);
            ws2812b_turn(i, (color_t)color_off);
            HAL_Delay(200);
        }
    }
}
Production/ISKBoard_QCTester/Core/Board/ws2812b.h
New file
@@ -0,0 +1,48 @@
/*
 * ws2812b.h
 *
 *  Created on: Jan 6, 2023
 *      Author: weihh
 */
#ifndef INC_WS2812B_H_
#define INC_WS2812B_H_
#include "stm32l4xx_hal.h"
#define WS2812_NUM    3
#define PIXEL_OFF     0          /* off   */
#define PIXEL_B       (0xFF<<0)  /* blue  */
#define PIXEL_R       (0xFF<<8)  /* red   */
#define PIXEL_G       (0xFF<<16) /* green */
#define PIXEL_W       (0xFFFFFF) /* white */
/* Composition of 24 bits data: GRB888
 * +----+----+----+----+----+----+----+----+----+
 * | G7 | ...| G0 | R7 | ...| R0 | B7 | ...| B0 |
 * +----+----+----+----+----+----+----+----+----+
 */
typedef struct pixel_s
{
    uint32_t    blue:8;
    uint32_t    red:8;
    uint32_t    green:8;
} pixel_t;
typedef union color_u
{
    pixel_t    pixel;
    uint32_t   data;
} color_t;
extern void ws2812b_init(void);
extern void ws2812b_reset(void);
extern int ws2812b_turn(int which, color_t color);
extern void ws2812b_blink(void);
#endif /* INC_WS2812B_H_ */
Production/ISKBoard_QCTester/Core/ESP/at-esp32.c
New file
@@ -0,0 +1,382 @@
/*
 * Copyright (c) 2022 Avnet
 * Author: Guo Wenxue <wenxue.guo@avnet.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GPL license.
 */
#include "at-esp32.h"
/*+------------------------+
 *|    Baisc AT command    |
 *+------------------------+*/
static inline int check_at_ready(comport_t *comport)
{
    int             times = 6;
    int             ready = 0;
    while( times-- )
    {
        if( 0 == send_atcmd_check_ok(comport, "AT", 500) )
        {
            ready = 1;
            break;
        }
    }
    return ready;
}
/* AT command: AT+RST */
int esp32_softreset(comport_t *comport)
{
    int             rv;
    rv = send_atcmd(comport, "AT+RST", 5000, "ready", AT_ERRSTR, NULL, 0);
    if( rv < 0)
    {
        log_error("send AT command to reset ESP32 failed, rv=%d\n", rv);
        return -1;
    }
    if( check_at_ready(comport) )
    {
        log_info("send AT to reset ESP32 and AT command ready\n");
        return 0;
    }
    else
    {
        log_info("send AT to reset ESP32 but AT command not ready\n");
        return -3;
    }
}
/* AT command: AT+RESTORE */
int esp32_restore(comport_t *comport)
{
    int             rv;
    //rv = send_atcmd_check_ok(comport, "AT+RESTORE", 5000);
    rv = send_atcmd(comport, "AT+RESTORE", 5000, "ready", AT_ERRSTR, NULL, 0);
    if( rv < 0)
    {
        log_error("send AT command to restore ESP32 failed, rv=%d\n", rv);
        return -1;
    }
    if( check_at_ready(comport) )
    {
        log_info("send AT command to resstore ESP32 ready\n");
        return 0;
    }
    else
    {
        log_error("send AT command to restore ESP32 but AT not ready\n");
        return -3;
    }
}
/* AT command: ATE1 or ATE0 */
int esp32_set_echo(comport_t *comport, int enable)
{
    char           *at = enable? "ATE1" : "ATE0";
    return send_atcmd_check_ok(comport, at, 500);
}
/* AT command: AT+GMR */
int esp32_get_firmware(comport_t *comport, char *version, int size)
{
    if( !version || size<=0 )
        return -1;
    return send_atcmd_check_value(comport, "AT+GMR", 2000, version, size);
}
/* AT command: AT+SYSSTORE */
int esp32_set_sysstore(comport_t *comport, int enable)
{
    char            at[ATCMD_LEN]={'\0'};
    snprintf(at, sizeof(at), "AT+SYSSTORE=%d", enable?1:0);
    return send_atcmd_check_ok(comport, at, 1000);
}
/*+------------------------+
 *|    WiFi AT command     |
 *+------------------------+*/
/* AT command: AT+CWMODE */
int esp32_set_wmode(comport_t *comport, workmode_t mode, int autoconn)
{
    char            at[ATCMD_LEN]={'\0'};
    snprintf(at, sizeof(at), "AT+CWMODE=%d,%d", mode, autoconn?1:0);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CIPSTAMAC/CIPAPMAC */
int esp32_get_macaddr(comport_t *comport, workmode_t mode, char *mac)
{
    if( !mac )
        return -1;
    if( MODE_SOFTAP == mode )
        return send_atcmd_check_request(comport, "AT+CIPAPMAC?", 3000, mac, MAC_LEN);
    else
        return send_atcmd_check_request(comport, "AT+CIPSTAMAC?", 3000, mac, MAC_LEN);
}
/* AT command: AT+CIPSTA/AT+CIPAP  */
int esp32_set_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway)
{
    char            at[ATCMD_LEN]={'\0'};
    if( !ip || !gateway )
        return -1;
    if( MODE_SOFTAP == mode )
        snprintf(at, sizeof(at), "AT+CIPAP=\"%s\",\"%s\"", ip, gateway);
    else
        snprintf(at, sizeof(at), "AT+CIPSTA=\"%s\",\"%s\"", ip, gateway);
    return send_atcmd_check_ok(comport, at, 2000);
}
/* AT command: AT+CIPSTA/AT+CIPAP  */
int esp32_get_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway)
{
    char           *at = MODE_SOFTAP==mode? "AT+CIPAP?" : "AT+CIPSTA?";
    char            buf[ATCMD_REPLY_LEN];
    int             rv;
    if( !ip || !gateway )
        return -1;
    rv = send_atcmd_check_value(comport, at, 3000, buf, sizeof(buf));
    if( rv < 0)
    {
        log_error("AT command query IP address failed, rv=%d\n", rv);
        return rv;
    }
    rv = parser_request_value(buf, "ip", ip, IP_LEN);
    if( rv < 0 )
    {
        log_error("Parser query IP address failed, rv=%d\n", rv);
        return rv;
    }
    rv = parser_request_value(buf, "gateway", gateway, IP_LEN);
    if( rv < 0 )
    {
        log_error("Parser query gateway address failed, rv=%d\n", rv);
        return rv;
    }
    return 0;
}
/* AT command: AT+CWDHCP */
int esp32_set_dhcp(comport_t *comport, workmode_t mode, int enable)
{
    char            at[ATCMD_LEN]={'\0'};
    snprintf(at, sizeof(at), "AT+CWDHCP=%d,%d", enable?1:0, mode);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CWAUTOCONN */
int esp32_set_autoconn(comport_t *comport, int enable)
{
    char            at[ATCMD_LEN]={'\0'};
    snprintf(at, sizeof(at), "AT+CWAUTOCONN=%d", enable?1:0);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CWLAP */
int esp32_list_ap(comport_t *comport, char *buf, int size)
{
    if( !buf || size<=0 )
        return -1;
    return send_atcmd_check_value(comport, "AT+CWLAP", 8000, buf, size);
}
/* AT command: AT+CWJAP */
int esp32_connect_ap(comport_t *comport, char *ssid, char *pwd)
{
    char            at[ATCMD_LEN]={'\0'};
    if( !ssid || !pwd )
        return -1;
    snprintf(at, sizeof(at), "AT+CWJAP=\"%s\",\"%s\"", ssid, pwd);
    return send_atcmd_check_ok(comport, at, 15000);
}
/* AT command: AT+CWQAP */
int esp32_disconn_ap(comport_t *comport)
{
    return send_atcmd_check_ok(comport, "AT+CWQAP", 5000);
}
/* AT command: AT+CWSTATE?  status value:
 * - 0: ESP32 station has not started any Wi-Fi connection.
 * - 1: ESP32 station has connected to an AP, but does not get an IPv4 address yet.
 * - 2: ESP32 station has connected to an AP, and got an IPv4 address.
 * - 3: ESP32 station is in Wi-Fi connecting or reconnecting state.
 * - 4: ESP32 station is in Wi-Fi disconnected state
 */
int esp32_join_status(comport_t *comport, int *status, char *ssid)
{
    char            buf[ATCMD_REPLY_LEN];
    int             rv;
    if( !status || !ssid )
        return -1;
    rv = send_atcmd_check_request(comport, "AT+CWSTATE?", 3000, buf, sizeof(buf));
    if( rv < 0)
    {
        log_error("AT command query join status failed, rv=%d\n", rv);
        return rv;
    }
    sscanf(buf, "%d,%s", status, ssid);
    return 0;
}
/* AT command:  AT+PING */
int esp32_ping(comport_t *comport, char *host, int timeout)
{
    char            at[ATCMD_LEN]={'\0'};
    if( !host )
        return -1;
    snprintf(at, sizeof(at), "AT+PING=\"%s\"", host);
    return send_atcmd_check_ok(comport, at, timeout);
}
/* AT command:  AT+CWSAP */
int esp32_set_softap(comport_t *comport, char *ssid, char *pwd, int channel, encmode_t encmode)
{
    char            at[ATCMD_LEN]={'\0'};
    if( !ssid || !pwd )
        return -1;
    snprintf(at, sizeof(at), "AT+CWSAP=\"%s\",\"%s\",%d,%d", ssid, pwd, channel, encmode);
    return send_atcmd_check_ok(comport, at, 5000);
}
/* AT command: AT+CWLIF */
int esp32_list_client(comport_t *comport, char *buf, int size)
{
    if( !buf || size<=0 )
        return -1;
    return send_atcmd_check_value(comport, "AT+CWLIF", 8000, buf, size);
}
/*+------------------------+
 *|   Socket AT command    |
 *+------------------------+*/
/* AT command: AT+CIPMUX */
int esp32_set_socket_mux(comport_t *comport, int enable)
{
    char            at[ATCMD_LEN]={'\0'};
    snprintf(at, sizeof(at), "AT+CIPMUX=%d", enable?1:0);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CIPSERVERMAXCONN */
int esp32_set_socket_clients(comport_t *comport, int max)
{
    char            at[ATCMD_LEN]={'\0'};
    if( max <= 0 )
        return -1;
    snprintf(at, sizeof(at), "AT+CIPSERVERMAXCONN=%d", max);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CIPSTO, timeout unit second */
int esp32_set_socket_timeout(comport_t *comport, int timeout)
{
    char            at[ATCMD_LEN]={'\0'};
    if( timeout <= 0 )
        return -1;
    snprintf(at, sizeof(at), "AT+CIPSTO=%d", timeout);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CIPSERVER */
int esp32_set_tcp_server(comport_t *comport, int port)
{
    char            at[ATCMD_LEN]={'\0'};
    if( port <= 0 )
        return -1;
    snprintf(at, sizeof(at), "AT+CIPSERVER=1,%d,\"TCP\"", port);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CIPSERVER */
int esp32_del_tcp_server(comport_t *comport, int port)
{
    char            at[ATCMD_LEN]={'\0'};
    if( port <= 0 )
        return -1;
    snprintf(at, sizeof(at), "AT+CIPSERVER=0,%d,\"TCP\"", port);
    return send_atcmd_check_ok(comport, at, 1500);
}
/* AT command: AT+CIPSTART */
int esp32_set_tcp_client(comport_t *comport, int mux, char *host, int port)
{
    char            at[ATCMD_LEN]={'\0'};
    char            buf[ATCMD_REPLY_LEN]={'\0'};
    int             keepalive = 60; /* unit second */
    int             rv,linkid = 0;
    if( !host || port <= 0 )
        return -1;
    rv = esp32_set_socket_mux(comport, mux);
    if(rv < 0)
        return rv;
    if( mux )
        snprintf(at, sizeof(at), "AT+CIPSTART=1,\"TCP\",\"%s\",%d,%d", host, port, keepalive);
    else
        snprintf(at, sizeof(at), "AT+CIPSTART=\"TCP\",\"%s\",%d,%d", host, port, keepalive);
    rv = send_atcmd_check_value(comport, at, 1500, buf, sizeof(buf));
    if(rv < 0)
        return rv;
    sscanf(buf, "%d,", &linkid);
    return linkid;
}
Production/ISKBoard_QCTester/Core/ESP/at-esp32.h
New file
@@ -0,0 +1,137 @@
/*
 * Copyright (c) 2022 Avnet
 * Author: Guo Wenxue <wenxue.guo@avnet.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GPL license.
 */
#ifndef  _AT_ESP32_H_
#define  _AT_ESP32_H_
#include "atcmd.h"
#if 0
enum
{
    DISABLE = 0,    /* common disable */
    ENABLE,         /* common enable  */
};
#endif
#define MAC_LEN     18 /* 11:22:33:44:55:66 */
#define IP_LEN      16 /* 255.255.255.255 */
/*+------------------------+
 *|    Baisc AT command    |
 *+------------------------+*/
/* AT command: AT+RST */
extern int esp32_softreset(comport_t *comport);
/* AT command: AT+RESTORE */
extern int esp32_restore(comport_t *comport);
/* AT command: ATE1 or ATE0 */
extern int esp32_set_echo(comport_t *comport, int enable);
/* AT command: AT+GMR */
extern int esp32_get_firmware(comport_t *comport, char *version, int size);
/* AT command: AT+SYSSTORE */
extern int esp32_set_sysstore(comport_t *comport, int enable);
/*+------------------------+
 *|    WiFi AT command     |
 *+------------------------+*/
typedef enum
{
    MODE_DISABLE=0, /* Wi-Fi RF will be disabled */
    MODE_STATION,   /* Station mode */
    MODE_SOFTAP,    /* SoftAP mode */
    MODE_WDS,       /* Wireless Distribution System: Both Station & SoftAP mode */
} workmode_t;
/* AT command: AT+CWMODE */
extern int esp32_set_wmode(comport_t *comport, workmode_t mode, int autoconn);
/* AT command: AT+CWDHCP */
extern int esp32_set_dhcp(comport_t *comport, workmode_t mode, int enable);
/* AT command: AT+CWAUTOCONN */
extern int esp32_set_autoconn(comport_t *comport, int enable);
/* AT command: AT+CIPSTAMAC/CIPAPMAC */
extern int esp32_get_macaddr(comport_t *comport, workmode_t mode, char *mac);
/* AT command: AT+CIPSTA/CIPAP */
extern int esp32_get_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway);
/* AT command: AT+CIPSTA/AT+CIPAP  */
extern int esp32_set_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway);
/* AT command: AT+CWLAP */
extern int esp32_list_ap(comport_t *comport, char *buf, int size);
/* AT command: AT+CWJAP */
extern int esp32_connect_ap(comport_t *comport, char *ssid, char *pwd);
/* AT command: AT+CWQAP */
extern int esp32_disconn_ap(comport_t *comport);
/* AT command: AT+CWSTATE? , status value:
 * - 0: ESP32 station has not started any Wi-Fi connection.
 * - 1: ESP32 station has connected to an AP, but does not get an IPv4 address yet.
 * - 2: ESP32 station has connected to an AP, and got an IPv4 address.
 * - 3: ESP32 station is in Wi-Fi connecting or reconnecting state.
 * - 4: ESP32 station is in Wi-Fi disconnected state
 */
extern int esp32_join_status(comport_t *comport, int *status, char *ssid);
/* AT command:  AT+PING */
extern int esp32_ping(comport_t *comport, char *host, int timeout);
/* AT command:  AT+CWSAP */
typedef enum
{
    MODE_OPEN,
    /* WEP not support */
    MODE_WPAPSK = 2,
    MODE_WPA2PSK,
    MODE_WPA_WPA2PSK,
} encmode_t;
extern int esp32_set_softap(comport_t *comport, char *ssid, char *pwd, int channel, encmode_t encmode);
/* AT command:  AT+CWLIF */
extern int esp32_list_client(comport_t *comport, char *buf, int size);
/*+------------------------+
 *|   Socket AT command    |
 *+------------------------+*/
/* AT command: CIPMUX */
extern int esp32_set_socket_mux(comport_t *comport, int enable);
/* AT command: AT+CIPSERVERMAXCONN */
extern int esp32_set_socket_clients(comport_t *comport, int max);
/* AT command: AT+CIPSTO, timeout unit second */
extern int esp32_set_socket_timeout(comport_t *comport, int timeout);
/* AT command: AT+CIPSERVER */
extern int esp32_set_tcp_server(comport_t *comport, int port);
/* AT command: AT+CIPSERVER */
extern int esp32_del_tcp_server(comport_t *comport, int port);
/* AT command: AT+CIPSTART */
extern int esp32_set_tcp_client(comport_t *comport, int mux, char *host, int port);
/*+------------------------+
 *|     BLE AT command     |
 *+------------------------+*/
// RFU
#endif   /* ----- #ifndef _AT_ESP32_H_  ----- */
Production/ISKBoard_QCTester/Core/ESP/atcmd.c
New file
@@ -0,0 +1,287 @@
/*
 * Copyright (c) 2022 Avnet
 * Author: Guo Wenxue <wenxue.guo@avnet.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GPL license.
 */
#include <ctype.h>
#include <string.h>
#include "atcmd.h"
/*  Description: this function used to send an AT command from serial port and wait for reply message from
 *               the communication module, and it will return once get expet/error string or timeout.
 *
 *    Arugments:
 *         $comport: the serial port which connected to GPRS/3G/4G/NB-IoT/WiFi/BLE/Zigbee/LoRa...
 *              $at: the AT command need to be sent, without "\r\n"
 *         $timeout: wait for module reply for AT command timeout value, unit micro seconds(ms)
 *          $exepct: the expect string reply from communication module
 *           $error: the error string reply from communication module
 *           $reply: the module reply message output buffer
 *            $size: the output buffer ($reply) size
 *
 * Return value: <0: Function error   0: Got expect string  1: Got error string   2: Receive until timeout
 *
 */
int send_atcmd(comport_t *comport, char *at, unsigned long timeout, char *expect, char *error, char *reply, int size)
{
    int                    rv = 0;
    int                    res = ATRES_TIMEOUT;
    int                    bytes = 0;
    char                   buf[ATCMD_REPLY_LEN] = {'\0'};
    char                   atcmd[ATCMD_LEN] = {'\0'};
    if( !comport || !at )
    {
        log_error("Invalid input arguments\n");
        return -1;
    }
    if( comport->fd <= 0 )
    {
        log_error("comport[%s] not opened\n", comport->devname);
        return -2;
    }
    /* flushes receive stream buffer */
    //xStreamBufferReset(comport->xRxStreamBuffer);
    snprintf(atcmd, sizeof(atcmd), "%s%s", at, AT_SUFFIX);
    rv=comport_send( comport, atcmd, strlen(atcmd) );
    if(rv < 0)
    {
        log_error("send command \"%s\" to \"%s\" failed, rv=%d\n", at, comport->devname, rv);
        return -3;
    }
    memset( buf, 0, sizeof(buf) );
    rv=comport_recv( comport, buf, sizeof(buf), timeout);
    if(rv < 0)
    {
        log_error("Wait for command \'%s\' reply failed, rv=%d\n", at, rv);
        return -4;
    }
    else if(rv == 0)
    {
        log_error("Wait for command \'%s\' reply timeout\n", at);
        return ATRES_TIMEOUT;
    }
    if( error && strstr(buf, error) )
    {
        log_debug("send command \"%s\" and got reply \"ERROR\"\n", at);
        return ATRES_ERROR;
    }
    if( expect && strstr(buf, expect) )
    {
        log_debug("send command \"%s\" and got reply \"OK\"\n", at);
        res = ATRES_EXPECT;
    }
    if( reply && size>0 )
    {
        bytes = strlen(buf)>size ? size : strlen(buf);
        memset(reply, 0, size);
        strncpy(reply, buf, bytes);
        log_debug("copy out command \"%s\" reply message: \n%s", at, reply);
    }
    return res;
}
/*
 *  Description: Send AT command which will only reply by "OK" or "ERROR", such as AT:
 *                 Reply:   \r\nOK\r\n
 * Return Value: 0: OK     -X: Failure
 */
int send_atcmd_check_ok(comport_t *comport, char *at, unsigned long timeout)
{
    int                     rv;
    if( !comport || !at )
    {
        log_error("Invalid input arguments\n");
        return -1;
    }
    rv=send_atcmd(comport, at, timeout, AT_OKSTR, AT_ERRSTR, NULL, 0);
    if( ATRES_EXPECT == rv )
    {
        return 0;
    }
    else
    {
        return -2;
    }
}
/*
 *  Description: Send AT command which will reply by a value directly in a single line, such as AT+CGMM:
 *                  Reply:   \r\nEC20F\r\nOK\r\n
 *
 * Return Value: 0: OK     -X: Failure
 */
int send_atcmd_check_value(comport_t *comport, char *at, unsigned long timeout, char *reply, int size)
{
    int                     rv, len;
    char                    buf[ATCMD_REPLY_LEN];
    char                   *ptr_start = buf;
    char                   *ptr_end;
    if( !comport || !at || !reply || size<=0 )
    {
        log_error("Invalid input arguments\n");
        return -1;
    }
    rv = send_atcmd(comport, at, timeout, AT_OKSTR, AT_ERRSTR, buf, ATCMD_REPLY_LEN);
    if( ATRES_EXPECT != rv )
    {
        log_error("send AT command \"%s\" failed, rv=%d\n", at, rv);
        return -2;
    }
    /* Skip the echo back command line */
    if( !strncmp(buf, at, strlen(at)) )
    {
        ptr_start=strchr(buf, '\n');
        if( !ptr_start )
        {
            log_error("reply message got wrong\n");
            return -3;
        }
        ptr_start++;   /* skip '\n'  */
    }
    /* find end reply string "\r\nOK\r\n"  */
    ptr_end = strstr(ptr_start, AT_OKSTR);
    if( ptr_end )
    {
        len = ptr_end - ptr_start;
    }
    else
    {
        len = strlen(buf) - (ptr_start-buf);
    }
    memset(reply, 0, size);
    len = len>size ? size : len;
    memcpy(reply, ptr_start, len);
    return 0;
}
/*
 *  Description: Parser the $value from $key like "xxx: " line, such as AT+CSQ:
 *                  Reply:   \r\n+CSQ: 26,99\r\nOK\r\n
 *
 * Return Value: 0: OK     -X: Failure
 */
int parser_request_value(char *buf, char *key, char *value, int size)
{
    char                   *ptr;
    int                    i = 0;
    if( !buf || !key || !value || size<=0 )
    {
        log_error("Invalid input arguments\n");
        return -1;
    }
    ptr = strstr(buf, key);
    if( !ptr )
    {
        log_debug("Not found key \"%s\" in %s\n", key, buf);
        return -2;
    }
    ptr=strchr(ptr, ':');  /* found ':' before the value */
    if( !ptr )
    {
        log_debug("Not found ':' before value\n");
        return -3;
    }
    ptr++;   /* skip ':'  */
    if( *ptr == '\"' ) /* skip " */
        ptr++;
    memset(value, 0, size);
    while(*ptr!='\r' && i<size-1)
    {
        if( !isspace(*(uint8_t *)ptr) && *ptr!='\"') /* skip space,\r,\n ...  */
            value[i++] = *ptr;
        ptr ++;
    }
    ptr++; /* skip  */
    return 0;
}
/*
 *  Description: Send AT command which will reply by the value  with a prefix "+CMD: " line, such as AT+CSQ:
 *                  Reply:   \r\n+CSQ: 26,99\r\nOK\r\n
 *
 * Return Value: 0: OK     -X: Failure
 */
int send_atcmd_check_request(comport_t *comport, char *at, unsigned long timeout, char *reply, int size)
{
    int                     i = 0;
    int                     rv;
    char                    buf[ATCMD_REPLY_LEN];
    char                   *ptr;
    if( !comport || !at || !reply || size<=0 )
    {
        log_error("Invalid input arguments\n");
        return -1;
    }
    rv = send_atcmd(comport, at, timeout, AT_OKSTR, AT_ERRSTR, buf, ATCMD_REPLY_LEN);
    if( ATRES_EXPECT != rv )
    {
        return -2;
    }
    ptr=strchr(buf, '+');  /* found '+' before the value */
    if( !ptr )
    {
        log_error("reply message got wrong\n");
        return -3;
    }
    ptr++;   /* skip '+'  */
    ptr=strchr(buf, ':');  /* found ':' before the value */
    if( !ptr )
    {
        log_error("reply message got wrong\n");
        return -3;
    }
    ptr++;   /* skip ':'  */
    if( *ptr == '\"' ) /* skip " */
        ptr++;
    memset(reply, 0, size);
    while(*ptr!='\r' && i<size-1)
    {
        if( !isspace(*(uint8_t *)ptr) && *ptr!='\"') /* skip space,\r,\n ...  */
            reply[i++] = *ptr;
        ptr ++;
    }
    return 0;
}
Production/ISKBoard_QCTester/Core/ESP/atcmd.h
New file
@@ -0,0 +1,88 @@
/*
 * Copyright (c) 2022 Avnet
 * Author: Guo Wenxue <wenxue.guo@avnet.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GPL license.
 */
#ifndef  _ATCMD_H_
#define  _ATCMD_H_
#include "comport.h"
#include "logger.h"
/* AT command common reply message max length  */
#define ATCMD_REPLY_LEN          512 /* Max AT command reply message length */
#define ATCMD_LEN                128 /* Max AT command length */
/* AT command reply message got expect or error string */
#define AT_OKSTR                 "\r\nOK\r\n"     /* expect string always be OK */
#define AT_ERRSTR                "\r\nERROR\r\n"  /* error string always be ERROR */
/* AT command should be end by $AT_SUFFIX */
#define AT_SUFFIX                "\r\n"
/* send_atcmd() return value status */
enum
{
    ATRES_EXPECT,   /* AT command reply got expect string, such as "OK\r\n" */
    ATRES_ERROR,    /* AT command reply got error string, such as "ERROR\r\n" */
    ATRES_TIMEOUT,  /* AT command not get error/expect string, receive until timeout */
};
/*  Description: this function used to send an AT command from serial port and wait for reply message from
 *               the communication module, and it will return once get expect/error string or timeout.
 *
 *    Arugments:
 *         $comport: the serial port which connected to GPRS/3G/4G/NB-IoT/WiFi/BLE/Zigbee/LoRa...
 *              $at: the AT command need to be sent, without "\r\n"
 *         $timeout: wait for module reply for AT command timeout value, unit micro seconds(ms)
 *          $exepct: the expect string reply from communication module
 *           $error: the error string reply from communication module
 *           $reply: the module reply message output buffer
 *            $size: the output buffer ($reply) size
 *
 * Return value: <0: Function error   0: Got expect string  1: Got error string   2: Receive until timeout
 *
 */
int send_atcmd(comport_t *comport, char *at, unsigned long timeout, char *expect, char *error, char *reply, int size);
/*
 *  Description: Send AT command which will only reply by "OK" or "ERROR", such as AT:
 *                  Reply:   \r\nOK\r\n
 *
 * Return Value:  0: OK     -X: ERROR
 */
int send_atcmd_check_ok(comport_t *comport, char *at, unsigned long timeout);
/*
 *  Description: Send AT command which will reply by a value directly in a single line, such as AT+CGMM:
 *                  Reply:   \r\nEC20F\r\nOK\r\n
 *
 * Return Value:  0: OK     -X: ERROR
 */
int send_atcmd_check_value(comport_t *comport, char *at, unsigned long timeout, char *reply, int size);
/*
 *  Description: Parser the $value from $key like "xxx: " line, such as AT+CSQ:
 *                  Reply:   \r\n+CSQ: 26,99\r\nOK\r\n
 *
 * Return Value: 0: OK     -X: Failure
 */
int parser_request_value(char *buf, char *key, char *value, int size);
/*
 *  Description: Send AT command which will reply by the value  with a prefix "+CMD: " line, such as AT+CSQ:
 *                  Reply:   \r\n+CSQ: 26,99\r\nOK\r\n
 *
 * Return Value:  0: OK     -X: ERROR
 */
int send_atcmd_check_request(comport_t *comport, char *at, unsigned long timeout, char *repy, int size);
#endif   /* ----- #ifndef _ATCMD_H_  ----- */
Production/ISKBoard_QCTester/Core/ESP/esp32.c
New file
@@ -0,0 +1,198 @@
/*
 * Copyright (c) 2022 Avnet
 * Author: Guo Wenxue <wenxue.guo@avnet.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GPL license.
 */
#include <string.h>
#include "esp32.h"
int esp32_hwreset(comport_t *comport)
{
    uint32_t        tickstart = 0;
    int             bytes;
    /* Clear the receive buffer */
    rb_clear(&comport->rb);
    /* Reset WiFi module by hardware GPIO */
    HAL_GPIO_WritePin(WiFiRst_GPIO_Port, WiFiRst_Pin, GPIO_PIN_RESET);
    HAL_Delay(500);
    HAL_GPIO_WritePin(WiFiRst_GPIO_Port, WiFiRst_Pin, GPIO_PIN_SET);
    /* Check module bootup information */
    tickstart = HAL_GetTick();
    while((HAL_GetTick() - tickstart) < 5000)
    {
        bytes = rb_data_size(&comport->rb);
        HAL_Delay( 100 );
        /* comport received data before but not receive in 100ms now, maybe data receive over */
        if( bytes>0 && rb_data_size(&comport->rb)==bytes )
        {
            break;
        }
    }
    /* WiFi module maybe not present */
    if( rb_data_size(&comport->rb) <= 0 )
    {
        printf("ERROR: WiFi module maybe not present\r\n");
        return -1;
    }
    /* Wait for 'ready' and cleanup */
    HAL_Delay(500);
    rb_clear(&comport->rb);
    return 0;
}
int esp32_init_module(comport_t *comport)
{
    int             rv;
    char            version[256] = {0};
    if( !comport )
        return -1;
    esp32_hwreset(comport);
    esp32_set_echo(comport, DISABLE);
    //esp32_set_sysstore(comport, ENABLE);
    rv = esp32_get_firmware(comport, version, sizeof(version));
    if( rv < 0)
    {
        log_error("Query ESP32 firmware version failed: %d\n", rv);
        return rv;
    }
    log_info("ESP32 firmware version:\n%s\n", version);
    return 0;
}
int esp32_setup_softap(comport_t *comport, char *ssid, char *pwd)
{
    esp32_set_wmode(comport, MODE_SOFTAP, ENABLE);
    esp32_set_ipaddr(comport, MODE_SOFTAP, DEF_SOFTAP_IPADDR, DEF_SOFTAP_IPADDR);
    esp32_set_dhcp(comport, MODE_SOFTAP, ENABLE);
    esp32_set_softap(comport, ssid, pwd, 11, MODE_WPA2PSK);
    return 0;
}
int esp32_join_network(comport_t *comport, char *ssid, char *pwd)
{
    int             rv, status = 0;
    int             times=10;
    char            buf[128] = {0};
    if( !comport )
        return -1;
    esp32_join_status(comport, &status, buf);
    if( 2==status && !strcmp(buf, ssid) )
    {
        log_info("ESP32 connected to \"%s\" already\n", ssid);
        return 0;
    }
    esp32_set_wmode(comport, MODE_STATION, ENABLE);
    esp32_set_dhcp(comport, MODE_STATION, ENABLE);
    rv = esp32_connect_ap(comport, ssid, pwd);
    if( rv < 0 )
    {
        log_error("connect to AP \"%s\" failed, rv=%d", ssid, rv);
        return rv;
    }
    while(times--)
    {
        rv = esp32_join_status(comport, &status, buf);
        if( 2 == status )
        {
            log_info("ESP32 connected to \"%s\" already\n", ssid);
            return 0;
        }
        rv = -3;
    }
    return rv;
}
int esp32_check_network(comport_t *comport)
{
    int             rv, times=5;
    char            ip[IP_LEN] = {0};
    char            gateway[IP_LEN] = {0};
    memset(ip, 0, sizeof(ip));
    memset(gateway, 0, sizeof(gateway));
    rv = esp32_get_ipaddr(comport, MODE_STATION, ip, gateway);
    if( rv<0 )
        return rv;
    if( !strlen(ip) || !strlen(gateway) )
        return -3;
    log_info("IP address: %s, netmask: %s\n", ip, gateway);
    while( times-- )
    {
        if( !(rv=esp32_ping(comport, gateway, 5000)) )
        {
            rv = 0;
            break;
        }
    }
    return 0;
}
int esp32_setup_tcp_server(comport_t *comport, int port)
{
    int             rv;
    rv = esp32_set_socket_mux(comport, ENABLE);
    if(rv<0)
        return rv;
    rv = esp32_set_socket_clients(comport, 2);
    if(rv<0)
        return rv;
    rv = esp32_set_tcp_server(comport, port);
    if(rv<0)
        return rv;
    rv = esp32_set_socket_timeout(comport, 600);
    if(rv<0)
        return rv;
    return 0;
}
int esp32_setup_tcp_client(comport_t *comport, char *host, int port)
{
    int             rv;
    rv = esp32_set_tcp_client(comport, DISABLE, host, port);
    if(rv<0)
        return rv;
    return 0;
}
Production/ISKBoard_QCTester/Core/ESP/esp32.h
New file
@@ -0,0 +1,32 @@
/*
 * Copyright (c) 2022 Avnet
 * Author: Guo Wenxue <wenxue.guo@avnet.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GPL license.
 */
#ifndef  _ESP32_H_
#define  _ESP32_H_
#include "at-esp32.h"
#define DEF_SOFTAP_IPADDR    "192.168.8.1"
#define DEF_SOFTAP_SSID      "Router_ESP32"
#define DEF_SOFTAP_PWD       "12345678"
extern int esp32_hwreset(comport_t *comport);
extern int esp32_init_module(comport_t *comport);
extern int esp32_setup_softap(comport_t *comport, char *ssid, char *pwd);
extern int esp32_join_network(comport_t *comport, char *ssid, char *pwd);
extern int esp32_check_network(comport_t *comport);
extern int esp32_setup_tcp_server(comport_t *comport, int port);
extern int esp32_setup_tcp_client(comport_t *comport, char *host, int port);
#endif   /* ----- #ifndef _ESP32_H_  ----- */
Production/ISKBoard_QCTester/Core/ESP/logger.h
New file
@@ -0,0 +1,31 @@
/*
 * logger.h
 *
 *  Created on: 2023年2月20日
 *      Author: Think
 */
#ifndef SRC_ESP_LOGGER_H_
#define SRC_ESP_LOGGER_H_
//#define CONFIG_ESP_DEBUG
#ifdef  CONFIG_ESP_DEBUG
#define log_error(format,args...) printf(format, ##args)
#define log_info(format,args...)  printf(format, ##args)
#define log_debug(format,args...)  printf(format, ##args)
#define log_trace(format,args...)  printf(format, ##args)
#else
#define log_error(format,args...) do{} while(0)
#define log_info(format,args...) do{} while(0)
#define log_debug(format,args...) do{} while(0)
#define log_trace(format,args...) do{} while(0)
#endif
#endif /* SRC_ESP_LOGGER_H_ */
Production/ISKBoard_QCTester/Core/Inc/adc.h
New file
@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    adc.h
  * @brief   This file contains all the function prototypes for
  *          the adc.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ADC_H__
#define __ADC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_ADC1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __ADC_H__ */
Production/ISKBoard_QCTester/Core/Inc/can.h
New file
@@ -0,0 +1,62 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    can.h
  * @brief   This file contains all the function prototypes for
  *          the can.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CAN_H__
#define __CAN_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
#include "usart.h"
#include "ringbuf.h"
/* USER CODE END Includes */
extern CAN_HandleTypeDef hcan1;
/* USER CODE BEGIN Private defines */
typedef struct can_s
{
    int                            fd;/* compatible with Linux API, not used */
    ring_buffer_t               xRxBuffer; /* receive data ring buffer */
} can_t;
extern can_t can;
/* USER CODE END Private defines */
void MX_CAN1_Init(void);
/* USER CODE BEGIN Prototypes */
extern can_t *can_init(CAN_HandleTypeDef *hcan);
extern int can_send(can_t *pcan, char *data, int bytes);
extern int can_recv(can_t *pcan, char *buf, int size, uint32_t timeout);
extern void can_term(can_t *pcan);
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __CAN_H__ */
Production/ISKBoard_QCTester/Core/Inc/gpio.h
New file
@@ -0,0 +1,49 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    gpio.h
  * @brief   This file contains all the function prototypes for
  *          the gpio.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_GPIO_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ GPIO_H__ */
Production/ISKBoard_QCTester/Core/Inc/main.h
New file
@@ -0,0 +1,116 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define StripLights_Pin GPIO_PIN_2
#define StripLights_GPIO_Port GPIOC
#define mikrobus_an_Pin GPIO_PIN_3
#define mikrobus_an_GPIO_Port GPIOC
#define mikrobus_pwm_Pin GPIO_PIN_1
#define mikrobus_pwm_GPIO_Port GPIOA
#define SPI1_CS_Pin GPIO_PIN_4
#define SPI1_CS_GPIO_Port GPIOA
#define LedBlue_Pin GPIO_PIN_2
#define LedBlue_GPIO_Port GPIOB
#define mikrobus_scl_Pin GPIO_PIN_10
#define mikrobus_scl_GPIO_Port GPIOB
#define mikrobus_sda_Pin GPIO_PIN_11
#define mikrobus_sda_GPIO_Port GPIOB
#define Key1_Pin GPIO_PIN_12
#define Key1_GPIO_Port GPIOB
#define Key1_EXTI_IRQn EXTI15_10_IRQn
#define Key2_Pin GPIO_PIN_13
#define Key2_GPIO_Port GPIOB
#define Key2_EXTI_IRQn EXTI15_10_IRQn
#define Key3_Pin GPIO_PIN_14
#define Key3_GPIO_Port GPIOB
#define Key3_EXTI_IRQn EXTI15_10_IRQn
#define LedGreen_Pin GPIO_PIN_6
#define LedGreen_GPIO_Port GPIOC
#define RS485_Dir_Pin GPIO_PIN_7
#define RS485_Dir_GPIO_Port GPIOC
#define CAN_STB_Pin GPIO_PIN_8
#define CAN_STB_GPIO_Port GPIOC
#define LedRed_Pin GPIO_PIN_9
#define LedRed_GPIO_Port GPIOC
#define mikrobus_cs_Pin GPIO_PIN_15
#define mikrobus_cs_GPIO_Port GPIOA
#define mikrobus_sck_Pin GPIO_PIN_10
#define mikrobus_sck_GPIO_Port GPIOC
#define mikrobus_miso_Pin GPIO_PIN_11
#define mikrobus_miso_GPIO_Port GPIOC
#define mikrobus_mosi_Pin GPIO_PIN_12
#define mikrobus_mosi_GPIO_Port GPIOC
#define Relay_Pin GPIO_PIN_2
#define Relay_GPIO_Port GPIOD
#define WiFiRst_Pin GPIO_PIN_3
#define WiFiRst_GPIO_Port GPIOB
#define mikrobus_int_Pin GPIO_PIN_4
#define mikrobus_int_GPIO_Port GPIOB
#define mikrobus_rst_Pin GPIO_PIN_5
#define mikrobus_rst_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
Production/ISKBoard_QCTester/Core/Inc/spi.h
New file
@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    spi.h
  * @brief   This file contains all the function prototypes for
  *          the spi.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_H__
#define __SPI_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern SPI_HandleTypeDef hspi1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_SPI1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __SPI_H__ */
Production/ISKBoard_QCTester/Core/Inc/stm32l4xx_hal_conf.h
New file
@@ -0,0 +1,482 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32l4xx_hal_conf.h
  * @author  MCD Application Team
  * @brief   HAL configuration template file.
  *          This file should be copied to the application folder and renamed
  *          to stm32l4xx_hal_conf.h.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32L4xx_HAL_CONF_H
#define STM32L4xx_HAL_CONF_H
#ifdef __cplusplus
 extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
  * @brief This is the list of modules to be used in the HAL driver
  */
#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
/*#define HAL_CRYP_MODULE_ENABLED   */
#define HAL_CAN_MODULE_ENABLED
/*#define HAL_COMP_MODULE_ENABLED   */
/*#define HAL_I2C_MODULE_ENABLED   */
/*#define HAL_CRC_MODULE_ENABLED   */
/*#define HAL_CRYP_MODULE_ENABLED   */
/*#define HAL_DAC_MODULE_ENABLED   */
/*#define HAL_DCMI_MODULE_ENABLED   */
/*#define HAL_DMA2D_MODULE_ENABLED   */
/*#define HAL_DFSDM_MODULE_ENABLED   */
/*#define HAL_DSI_MODULE_ENABLED   */
/*#define HAL_FIREWALL_MODULE_ENABLED   */
/*#define HAL_GFXMMU_MODULE_ENABLED   */
/*#define HAL_HCD_MODULE_ENABLED   */
/*#define HAL_HASH_MODULE_ENABLED   */
/*#define HAL_I2S_MODULE_ENABLED   */
/*#define HAL_IRDA_MODULE_ENABLED   */
/*#define HAL_IWDG_MODULE_ENABLED   */
/*#define HAL_LTDC_MODULE_ENABLED   */
/*#define HAL_LCD_MODULE_ENABLED   */
/*#define HAL_LPTIM_MODULE_ENABLED   */
/*#define HAL_MMC_MODULE_ENABLED   */
/*#define HAL_NAND_MODULE_ENABLED   */
/*#define HAL_NOR_MODULE_ENABLED   */
/*#define HAL_OPAMP_MODULE_ENABLED   */
/*#define HAL_OSPI_MODULE_ENABLED   */
/*#define HAL_OSPI_MODULE_ENABLED   */
/*#define HAL_PCD_MODULE_ENABLED   */
/*#define HAL_PKA_MODULE_ENABLED   */
/*#define HAL_QSPI_MODULE_ENABLED   */
/*#define HAL_QSPI_MODULE_ENABLED   */
/*#define HAL_RNG_MODULE_ENABLED   */
/*#define HAL_RTC_MODULE_ENABLED   */
/*#define HAL_SAI_MODULE_ENABLED   */
/*#define HAL_SD_MODULE_ENABLED   */
/*#define HAL_SMBUS_MODULE_ENABLED   */
/*#define HAL_SMARTCARD_MODULE_ENABLED   */
#define HAL_SPI_MODULE_ENABLED
/*#define HAL_SRAM_MODULE_ENABLED   */
/*#define HAL_SWPMI_MODULE_ENABLED   */
#define HAL_TIM_MODULE_ENABLED
/*#define HAL_TSC_MODULE_ENABLED   */
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED   */
/*#define HAL_WWDG_MODULE_ENABLED   */
/*#define HAL_EXTI_MODULE_ENABLED   */
/*#define HAL_PSSI_MODULE_ENABLED   */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_EXTI_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## Oscillator Values adaptation ####################*/
/**
  * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
  *        This value is used by the RCC HAL module to compute the system frequency
  *        (when HSE is used as system clock source, directly or through the PLL).
  */
#if !defined  (HSE_VALUE)
  #define HSE_VALUE    ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined  (HSE_STARTUP_TIMEOUT)
  #define HSE_STARTUP_TIMEOUT    ((uint32_t)100U)   /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
  * @brief Internal Multiple Speed oscillator (MSI) default value.
  *        This value is the default MSI range value after Reset.
  */
#if !defined  (MSI_VALUE)
  #define MSI_VALUE    ((uint32_t)4000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
/**
  * @brief Internal High Speed oscillator (HSI) value.
  *        This value is used by the RCC HAL module to compute the system frequency
  *        (when HSI is used as system clock source, directly or through the PLL).
  */
#if !defined  (HSI_VALUE)
  #define HSI_VALUE    ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
  * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG.
  *        This internal oscillator is mainly dedicated to provide a high precision clock to
  *        the USB peripheral by means of a special Clock Recovery System (CRS) circuitry.
  *        When the CRS is not used, the HSI48 RC oscillator runs on it default frequency
  *        which is subject to manufacturing process variations.
  */
#if !defined  (HSI48_VALUE)
 #define HSI48_VALUE   ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz.
                                              The real value my vary depending on manufacturing process variations.*/
#endif /* HSI48_VALUE */
/**
  * @brief Internal Low Speed oscillator (LSI) value.
  */
#if !defined  (LSI_VALUE)
 #define LSI_VALUE  32000U       /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */                      /*!< Value of the Internal Low Speed oscillator in Hz
                                             The real value may vary depending on the variations
                                             in voltage and temperature.*/
/**
  * @brief External Low Speed oscillator (LSE) value.
  *        This value is used by the UART, RTC HAL module to compute the system frequency
  */
#if !defined  (LSE_VALUE)
  #define LSE_VALUE    32768U /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined  (LSE_STARTUP_TIMEOUT)
  #define LSE_STARTUP_TIMEOUT    5000U   /*!< Time out for LSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
  * @brief External clock source for SAI1 peripheral
  *        This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
  *        frequency.
  */
#if !defined  (EXTERNAL_SAI1_CLOCK_VALUE)
  #define EXTERNAL_SAI1_CLOCK_VALUE    2097000U /*!< Value of the SAI1 External clock source in Hz*/
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
/**
  * @brief External clock source for SAI2 peripheral
  *        This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
  *        frequency.
  */
#if !defined  (EXTERNAL_SAI2_CLOCK_VALUE)
  #define EXTERNAL_SAI2_CLOCK_VALUE    48000U /*!< Value of the SAI2 External clock source in Hz*/
#endif /* EXTERNAL_SAI2_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
   ===  you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
  * @brief This is the HAL system configuration section
  */
#define  VDD_VALUE                      3300U /*!< Value of VDD in mv */
#define  TICK_INT_PRIORITY            15U    /*!< tick interrupt priority */
#define  USE_RTOS                     0U
#define  PREFETCH_ENABLE              0U
#define  INSTRUCTION_CACHE_ENABLE     1U
#define  DATA_CACHE_ENABLE            1U
/* ########################## Assert Selection ############################## */
/**
  * @brief Uncomment the line below to expanse the "assert_param" macro in the
  *        HAL drivers code
  */
/* #define USE_FULL_ASSERT    1U */
/* ################## Register callback feature configuration ############### */
/**
  * @brief Set below the peripheral configuration  to "1U" to add the support
  *        of HAL callback registration/deregistration feature for the HAL
  *        driver(s). This allows user application to provide specific callback
  *        functions thanks to HAL_PPP_RegisterCallback() rather than overwriting
  *        the default weak callback functions (see each stm32l4xx_hal_ppp.h file
  *        for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef
  *        for each PPP peripheral).
  */
#define USE_HAL_ADC_REGISTER_CALLBACKS        0U
#define USE_HAL_CAN_REGISTER_CALLBACKS        0U
#define USE_HAL_COMP_REGISTER_CALLBACKS       0U
#define USE_HAL_CRYP_REGISTER_CALLBACKS       0U
#define USE_HAL_DAC_REGISTER_CALLBACKS        0U
#define USE_HAL_DCMI_REGISTER_CALLBACKS       0U
#define USE_HAL_DFSDM_REGISTER_CALLBACKS      0U
#define USE_HAL_DMA2D_REGISTER_CALLBACKS      0U
#define USE_HAL_DSI_REGISTER_CALLBACKS        0U
#define USE_HAL_GFXMMU_REGISTER_CALLBACKS     0U
#define USE_HAL_HASH_REGISTER_CALLBACKS       0U
#define USE_HAL_HCD_REGISTER_CALLBACKS        0U
#define USE_HAL_I2C_REGISTER_CALLBACKS        0U
#define USE_HAL_IRDA_REGISTER_CALLBACKS       0U
#define USE_HAL_LPTIM_REGISTER_CALLBACKS      0U
#define USE_HAL_LTDC_REGISTER_CALLBACKS       0U
#define USE_HAL_MMC_REGISTER_CALLBACKS        0U
#define USE_HAL_OPAMP_REGISTER_CALLBACKS      0U
#define USE_HAL_OSPI_REGISTER_CALLBACKS       0U
#define USE_HAL_PCD_REGISTER_CALLBACKS        0U
#define USE_HAL_QSPI_REGISTER_CALLBACKS       0U
#define USE_HAL_RNG_REGISTER_CALLBACKS        0U
#define USE_HAL_RTC_REGISTER_CALLBACKS        0U
#define USE_HAL_SAI_REGISTER_CALLBACKS        0U
#define USE_HAL_SD_REGISTER_CALLBACKS         0U
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS  0U
#define USE_HAL_SMBUS_REGISTER_CALLBACKS      0U
#define USE_HAL_SPI_REGISTER_CALLBACKS        0U
#define USE_HAL_SWPMI_REGISTER_CALLBACKS      0U
#define USE_HAL_TIM_REGISTER_CALLBACKS        0U
#define USE_HAL_TSC_REGISTER_CALLBACKS        0U
#define USE_HAL_UART_REGISTER_CALLBACKS       0U
#define USE_HAL_USART_REGISTER_CALLBACKS      0U
#define USE_HAL_WWDG_REGISTER_CALLBACKS       0U
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
 * Activated: CRC code is present inside driver
 * Deactivated: CRC code cleaned from driver
 */
#define USE_SPI_CRC                   0U
/* Includes ------------------------------------------------------------------*/
/**
  * @brief Include module's header file
  */
#ifdef HAL_RCC_MODULE_ENABLED
  #include "stm32l4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
  #include "stm32l4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
  #include "stm32l4xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
  #include "stm32l4xx_hal_dfsdm.h"
#endif /* HAL_DFSDM_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
  #include "stm32l4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
  #include "stm32l4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
  #include "stm32l4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
  #include "Legacy/stm32l4xx_hal_can_legacy.h"
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED
  #include "stm32l4xx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
  #include "stm32l4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
  #include "stm32l4xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
  #include "stm32l4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_DCMI_MODULE_ENABLED
  #include "stm32l4xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
  #include "stm32l4xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DSI_MODULE_ENABLED
  #include "stm32l4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
  #include "stm32l4xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_GFXMMU_MODULE_ENABLED
  #include "stm32l4xx_hal_gfxmmu.h"
#endif /* HAL_GFXMMU_MODULE_ENABLED */
#ifdef HAL_FIREWALL_MODULE_ENABLED
  #include "stm32l4xx_hal_firewall.h"
#endif /* HAL_FIREWALL_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
  #include "stm32l4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
  #include "stm32l4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
  #include "stm32l4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
  #include "stm32l4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
  #include "stm32l4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
  #include "stm32l4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LCD_MODULE_ENABLED
  #include "stm32l4xx_hal_lcd.h"
#endif /* HAL_LCD_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
  #include "stm32l4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
  #include "stm32l4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
  #include "stm32l4xx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
  #include "stm32l4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
  #include "stm32l4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_OPAMP_MODULE_ENABLED
  #include "stm32l4xx_hal_opamp.h"
#endif /* HAL_OPAMP_MODULE_ENABLED */
#ifdef HAL_OSPI_MODULE_ENABLED
  #include "stm32l4xx_hal_ospi.h"
#endif /* HAL_OSPI_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
  #include "stm32l4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_PKA_MODULE_ENABLED
  #include "stm32l4xx_hal_pka.h"
#endif /* HAL_PKA_MODULE_ENABLED */
#ifdef HAL_PSSI_MODULE_ENABLED
  #include "stm32l4xx_hal_pssi.h"
#endif /* HAL_PSSI_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
  #include "stm32l4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
  #include "stm32l4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
  #include "stm32l4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
  #include "stm32l4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
  #include "stm32l4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
  #include "stm32l4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
  #include "stm32l4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
  #include "stm32l4xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
  #include "stm32l4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
  #include "stm32l4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_SWPMI_MODULE_ENABLED
  #include "stm32l4xx_hal_swpmi.h"
#endif /* HAL_SWPMI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
  #include "stm32l4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_TSC_MODULE_ENABLED
  #include "stm32l4xx_hal_tsc.h"
#endif /* HAL_TSC_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
  #include "stm32l4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
  #include "stm32l4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
  #include "stm32l4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param  expr If expr is false, it calls assert_failed function
  *         which reports the name of the source file and the source
  *         line number of the call that failed.
  *         If expr is true, it returns no value.
  * @retval None
  */
  #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
  void assert_failed(uint8_t *file, uint32_t line);
#else
  #define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* STM32L4xx_HAL_CONF_H */
Production/ISKBoard_QCTester/Core/Inc/stm32l4xx_it.h
New file
@@ -0,0 +1,72 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32l4xx_it.h
  * @brief   This file contains the headers of the interrupt handlers.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
 ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L4xx_IT_H
#define __STM32L4xx_IT_H
#ifdef __cplusplus
 extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void CAN1_RX0_IRQHandler(void);
void USART1_IRQHandler(void);
void USART2_IRQHandler(void);
void USART3_IRQHandler(void);
void EXTI15_10_IRQHandler(void);
void LPUART1_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32L4xx_IT_H */
Production/ISKBoard_QCTester/Core/Inc/tim.h
New file
@@ -0,0 +1,57 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    tim.h
  * @brief   This file contains all the function prototypes for
  *          the tim.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TIM_H__
#define __TIM_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim6;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_TIM1_Init(void);
void MX_TIM6_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __TIM_H__ */
Production/ISKBoard_QCTester/Core/Inc/usart.h
New file
@@ -0,0 +1,61 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    usart.h
  * @brief   This file contains all the function prototypes for
  *          the usart.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern UART_HandleTypeDef hlpuart1;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_LPUART1_UART_Init(void);
void MX_USART1_UART_Init(void);
void MX_USART2_UART_Init(void);
void MX_USART3_UART_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __USART_H__ */
Production/ISKBoard_QCTester/Core/Src/adc.c
New file
@@ -0,0 +1,163 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    adc.c
  * @brief   This file provides code for the configuration
  *          of the ADC instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "adc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
ADC_HandleTypeDef hadc1;
/* ADC1 init function */
void MX_ADC1_Init(void)
{
  /* USER CODE BEGIN ADC1_Init 0 */
  /* USER CODE END ADC1_Init 0 */
  ADC_ChannelConfTypeDef sConfig = {0};
  /* USER CODE BEGIN ADC1_Init 1 */
  /* USER CODE END ADC1_Init 1 */
  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 2;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_15;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_16;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
  /* USER CODE END ADC1_Init 2 */
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */
  /* USER CODE END ADC1_MspInit 0 */
  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
    PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
    PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
    PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
    PeriphClkInit.PLLSAI1.PLLSAI1N = 9;
    PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
    PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
    PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV6;
    PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_ADC1CLK;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
    /* ADC1 clock enable */
    __HAL_RCC_ADC_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PB0     ------> ADC1_IN15
    PB1     ------> ADC1_IN16
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  /* USER CODE BEGIN ADC1_MspInit 1 */
  /* USER CODE END ADC1_MspInit 1 */
  }
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspDeInit 0 */
  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC_CLK_DISABLE();
    /**ADC1 GPIO Configuration
    PB0     ------> ADC1_IN15
    PB1     ------> ADC1_IN16
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0|GPIO_PIN_1);
  /* USER CODE BEGIN ADC1_MspDeInit 1 */
  /* USER CODE END ADC1_MspDeInit 1 */
  }
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Production/ISKBoard_QCTester/Core/Src/can.c
New file
@@ -0,0 +1,293 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    can.c
  * @brief   This file provides code for the configuration
  *          of the CAN instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"
/* USER CODE BEGIN 0 */
#include "comport.h"
//#define CONFIG_CAN_DEBUG
#ifdef  CONFIG_CAN_DEBUG
#define can_print(format,args...) printf(format, ##args)
#else
#define can_print(format,args...) do{} while(0)
#endif
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
  /* USER CODE BEGIN CAN1_Init 0 */
    CAN_FilterTypeDef can1FilterConfig;
  /* USER CODE END CAN1_Init 0 */
  /* USER CODE BEGIN CAN1_Init 1 */
  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 10;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_6TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */
  can1FilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  can1FilterConfig.FilterIdHigh = 0x0000;
  can1FilterConfig.FilterIdLow = 0x0000;
  can1FilterConfig.FilterMaskIdHigh = 0x0000;
  can1FilterConfig.FilterMaskIdLow = 0x0000;
  can1FilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  can1FilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  can1FilterConfig.FilterBank = 0;
  can1FilterConfig.SlaveStartFilterBank = 13;
  can1FilterConfig.FilterActivation = CAN_FILTER_ENABLE; //使能过滤ï¿????
  if(HAL_CAN_ConfigFilter(&hcan1, &can1FilterConfig) != HAL_OK)
  {
      Error_Handler();
  }
  if(HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
      Error_Handler();
  }
  can_init(&hcan1);
  /* USER CODE END CAN1_Init 2 */
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */
  /* USER CODE END CAN1_MspInit 0 */
    /* CAN1 clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN1 GPIO Configuration
    PB8     ------> CAN1_RX
    PB9     ------> CAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspInit 1 */
  /* USER CODE END CAN1_MspInit 1 */
  }
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspDeInit 0 */
  /* USER CODE END CAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();
    /**CAN1 GPIO Configuration
    PB8     ------> CAN1_RX
    PB9     ------> CAN1_TX
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9);
    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspDeInit 1 */
  /* USER CODE END CAN1_MspDeInit 1 */
  }
}
/* USER CODE BEGIN 1 */
can_t can={-1, NULL};
uint8_t aRxData[COMM_RXBUFSIZE];//不能太小
CAN_RxHeaderTypeDef         hCAN1_RxHeader; //接收报文定义结构ï¿???
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    can_t                      *cans = &can;
    uint8_t                  i;
    /* Check can receive ringbuffer */
    if( cans->fd<0 || !cans->xRxBuffer.buffer || !rb_free_size(&cans->xRxBuffer) )
    {
        return;
    }
    /* Put the receive byte data into Ringbuffer */
    if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &hCAN1_RxHeader, aRxData) == HAL_OK)
    {
        can_print("\r\nGet Rx Message Success!!\r\n");
        can_print("[ID]:0x%lX [DLC]:%ld [Data]:", hCAN1_RxHeader.StdId, hCAN1_RxHeader.DLC);
        for(i=0; i<hCAN1_RxHeader.DLC; i++)
            can_print("%X ", aRxData[i]);
        can_print("\r\n");
    }
    else
    {
        can_print("\r\nGet Rx Message error!!\r\n");
        return;
    }
    rb_write(&cans->xRxBuffer, aRxData, 8);
}
can_t *can_init(CAN_HandleTypeDef *hcan)
{
    can_t              *cans = &can;
    rb_init(&can.xRxBuffer, aRxData, sizeof(aRxData));
    // 触发唤醒的字节数,流缓冲区中必须存在不少该字节数的数据才能唤醒等待数据的任务
    //(设置为0时,将按照如1的方式处理,设置的数比buffer_size还大时,创建无效ï¿???
    if( !cans )
    {
        return NULL;
    }
    can.fd = 3;
    if (HAL_CAN_Start(&hcan1) != HAL_OK)    //å¼?启CAN
    {
        can_print("start can Error_Handler ....\r\n");
        Error_Handler();
    }
    return cans;
}
void can_term(can_t *pcan)
{
    if( !pcan )
        return;
    pcan->fd = -1;
    if( pcan->xRxBuffer.buffer )
    {
        rb_clear(&pcan->xRxBuffer);
    }
    return;
}
/*
 * @brief: CAN Send Message.
 * @param: "TxData[]" stored the message of ready to send, which length must between 0 and 8.
 * @param: "length" stored the number of the data (one data is 8 bit) of ready to send.
 * @retval: Tx_Error: send error; other: the mailbox which has been used, this parameter can be a CAN_TX_MAILBOX0,
 *                                                                                            CAN_TX_MAILBOX1,
 *                                                                                            CAN_TX_MAILBOX2.
 */
CAN_TxHeaderTypeDef          Tx_pHeader;     //发�?�报文定义结构体
int can_send(can_t *pcan, char *data, int bytes)
{
    if( !pcan || !data || bytes<=0 )
    {
        return -1;
    }
    //发�?�函数的改写
    uint32_t TxMailboxNumber = 0x00000000U;    // 存储本次发�?�所使用邮箱的邮箱号
    Tx_pHeader.StdId = 0x122;    /*!标准ID。参数�?�只能是 0 ï¿??? 0x7FF(二进制的11ï¿???1) */
    Tx_pHeader.ExtId = 0x0000;      /*!扩展ID。参数�?�只能是 0 ï¿??? 0x1FFFFFFF(二进制的29ï¿???1)*/
    Tx_pHeader.IDE = CAN_ID_STD;    /*!IDE。HAL库编程时,标准帧填写CAN_ID_STD,扩展帧填写CAN_ID_EXT */
    Tx_pHeader.RTR = CAN_RTR_DATA;  /*!RTR。HAL库编程时,数据帧填写CAN_RTR_DATA,遥控帧填写CAN_RTR_REMOTE */
    Tx_pHeader.DLC = bytes;    /*!DLC。数据长度,参数值只能是 0 ï¿??? 8 */
    Tx_pHeader.TransmitGlobalTime = DISABLE;
    //ï¿??? Tx é‚®ç®±ä¸­å¢žåŠ ä¸€ä¸ªæ¶ˆï¿???,并且ï¿???活对应的传输请求
    if(HAL_CAN_AddTxMessage(&hcan1, &Tx_pHeader, (uint8_t *)data, &TxMailboxNumber) != HAL_OK)
    {
        return -1;
    }
    return 0;
}
int can_recv(can_t *pcan, char *buf, int size, uint32_t timeout)
{
    uint32_t          tickstart = 0;
    size_t            bytes = 0;
    if( !pcan || !buf || size<=0 )
        return -1;
    if( !pcan->xRxBuffer.buffer )
        return -2;
    tickstart = HAL_GetTick();
//    bytes = rb_data_size(&can->xRxBuffer);
    can_print("bytes is %d\r\n", bytes);
    while((HAL_GetTick() - tickstart) < timeout)
    {
        bytes = rb_data_size(&pcan->xRxBuffer);
        HAL_Delay(10);
        /* can received data before but not receive in 10ms now, maybe data receive over */
        if( bytes>0 && rb_data_size(&pcan->xRxBuffer)==bytes )
        {
            break;
        }
    }
    bytes = rb_data_size( &pcan->xRxBuffer );
    if( !bytes )
    {
        return 0;
    }
    bytes = bytes>size ? size : bytes;
    can_print("bytes=%d size=%d\r\n", bytes, size);
    rb_read(&pcan->xRxBuffer, (uint8_t *)buf, bytes);
    return bytes;
}
/* USER CODE END 1 */
Production/ISKBoard_QCTester/Core/Src/gpio.c
New file
@@ -0,0 +1,130 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    gpio.c
  * @brief   This file provides code for the configuration
  *          of all used GPIO pins.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure GPIO                                                             */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, StripLights_Pin|mikrobus_an_Pin|RS485_Dir_Pin|CAN_STB_Pin
                          |mikrobus_sck_Pin|mikrobus_miso_Pin|mikrobus_mosi_Pin, GPIO_PIN_RESET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, LedBlue_Pin|WiFiRst_Pin, GPIO_PIN_SET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, mikrobus_scl_Pin|mikrobus_sda_Pin|mikrobus_int_Pin|mikrobus_rst_Pin, GPIO_PIN_RESET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, LedGreen_Pin|LedRed_Pin, GPIO_PIN_SET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(mikrobus_cs_GPIO_Port, mikrobus_cs_Pin, GPIO_PIN_RESET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(Relay_GPIO_Port, Relay_Pin, GPIO_PIN_RESET);
  /*Configure GPIO pins : PCPin PCPin PCPin PCPin
                           PCPin PCPin PCPin PCPin
                           PCPin */
  GPIO_InitStruct.Pin = StripLights_Pin|mikrobus_an_Pin|LedGreen_Pin|RS485_Dir_Pin
                          |CAN_STB_Pin|LedRed_Pin|mikrobus_sck_Pin|mikrobus_miso_Pin
                          |mikrobus_mosi_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = mikrobus_pwm_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(mikrobus_pwm_GPIO_Port, &GPIO_InitStruct);
  /*Configure GPIO pins : PAPin PAPin */
  GPIO_InitStruct.Pin = SPI1_CS_Pin|mikrobus_cs_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  /*Configure GPIO pins : PBPin PBPin PBPin PBPin
                           PBPin PBPin */
  GPIO_InitStruct.Pin = LedBlue_Pin|mikrobus_scl_Pin|mikrobus_sda_Pin|WiFiRst_Pin
                          |mikrobus_int_Pin|mikrobus_rst_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  /*Configure GPIO pins : PBPin PBPin PBPin */
  GPIO_InitStruct.Pin = Key1_Pin|Key2_Pin|Key3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = Relay_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(Relay_GPIO_Port, &GPIO_InitStruct);
  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
Production/ISKBoard_QCTester/Core/Src/main.c
New file
@@ -0,0 +1,703 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "can.h"
#include "usart.h"
#include "spi.h"
#include "tim.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include "miscdev.h"
#include "ds18b20.h"
#include "sht20.h"
#include "isl1208.h"
#include "ws2812b.h"
#include "w25q32.h"
#include "comport.h"
#include "hal_oled.h"
#include "esp32.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define POS_X       5
#define POS_Y       1
#define SHOWTIME    800
#define BLOCK_TIME        0XFFFFFFFF
static inline void oled_show(char *msg)
{
    OLED_Init();
    OLED_ShowString(POS_X, POS_Y, msg, OLED_FONT16);
    HAL_Delay(SHOWTIME);
}
int test_beep(void);
int test_relay(void);
int test_led(void);
int test_wifi(void);
int test_adc(void);
int test_spiflash(void);
int test_ds18b20(void);
int test_sht20(void);
int test_rtc(void);
int test_usart3(void);
int test_can(void);
int test_rs485(void);
int test_mikrobus(void);
/* USER CODE END 0 */
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
    rtc_time_t       tm = { .tm_year=2023, .tm_mon=4, .tm_mday=2, .tm_hour=6, .tm_min=6, .tm_sec=6 };
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_USART1_UART_Init();
  MX_LPUART1_UART_Init();
  MX_ADC1_Init();
  MX_TIM6_Init();
  MX_TIM1_Init();
  MX_SPI1_Init();
  MX_CAN1_Init();
  /* USER CODE BEGIN 2 */
  printf("Welcome to ISKBoard v1.0\r\n");
  OLED_Init();
  ws2812b_init();
  set_rtc_time(tm);
  test_beep();
  test_relay();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      test_mikrobus();
      test_spiflash();
      test_rtc();
      test_wifi();
      test_adc();
      test_ds18b20();
      test_sht20();
      test_usart3();
      test_can();
      test_rs485();
      test_led();
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}
/* USER CODE BEGIN 4 */
int test_beep(void)
{
    printf("Buzzer                    [TEST]\r\n");
    oled_show("Beep [TEST]");
    beep_start(2, 300);
    printf("\r\n");
    return 0;
}
int test_relay(void)
{
    printf("Relay                     [TEST]\r\n");
    oled_show("Relay [TEST]");
    turn_relay(ON);
    HAL_Delay(800);
    turn_relay(OFF);
    printf("\r\n");
    return 0;
}
#define MIKROBUS_PIN_GROUP      5
static gpio_t  mikrobus_pins[MIKROBUS_PIN_GROUP][2] =
{
        { {"AN", mikrobus_an_GPIO_Port, mikrobus_an_Pin}, {"RST", mikrobus_rst_GPIO_Port, mikrobus_rst_Pin} },
        { {"CS", mikrobus_cs_GPIO_Port, mikrobus_cs_Pin}, {"SCK", mikrobus_sck_GPIO_Port, mikrobus_sck_Pin} },
        { {"MISO", mikrobus_miso_GPIO_Port, mikrobus_miso_Pin}, {"MOSI", mikrobus_mosi_GPIO_Port, mikrobus_mosi_Pin} },
        { {"PWM", mikrobus_pwm_GPIO_Port, mikrobus_pwm_Pin}, {"INT", mikrobus_int_GPIO_Port, mikrobus_int_Pin} },
        /* RX3/TX3 initial as comport before, and test as comport but not GPIO mode */
        { {"SCL", mikrobus_scl_GPIO_Port, mikrobus_scl_Pin}, {"SDA", mikrobus_sda_GPIO_Port, mikrobus_sda_Pin} },
};
#define PIN_OUTPUT         1
#define PIN_INPUT          0
void set_gpio_mode(gpio_t pin, int mode)
{
    GPIO_InitTypeDef    GPIO_InitStruct = {0};
    if( PIN_INPUT == mode )
    {
        GPIO_InitStruct.Pin = pin.pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(pin.group, &GPIO_InitStruct);
    }
    else
    {
        GPIO_InitStruct.Pin = pin.pin;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        HAL_GPIO_Init(pin.group, &GPIO_InitStruct);
    }
}
int comport_test(UART_HandleTypeDef *huart)
{
    comport_t          *comport = NULL;
    char                buf[32] = { 0 };
    int                 rv = 0;
    comport = comport_open(huart);
    if( !comport )
    {
        //printf("%s() comport open failed\r\n", __func__);
        return -2;
    }
    comport_flush(comport);
    comport_send(comport, "ISKBoard", strlen("ISKBoard"));
    comport_recv(comport, buf, sizeof(buf), 50);
//    printf("%s() receive: %s\r\n", __func__, buf);
    if( strcmp(buf, "ISKBoard") )
    {
        rv = -3;
        goto cleanup;
    }
cleanup:
    comport_term(comport);
    return rv;
}
int rs485_test(UART_HandleTypeDef *huart)
{
    comport_t          *comport_rs485 = NULL;
    char                buf[32] = { 0 };
    int                 rv = 0;
    comport_rs485 = comport_open(huart);
    if( !comport_rs485 )
    {
        //printf("%s() comport open failed\r\n", __func__);
        return -2;
    }
    comport_flush(comport_rs485);
    rs485_recv(comport_rs485, buf, sizeof(buf), BLOCK_TIME);
//    printf("%s() receive: %s\r\n", __func__, buf);
    if( !strstr(buf, "PC2ISKBoard-RS485") )
    {
        rv = -3;
        goto cleanup;
    }else
    {
        rs485_send(comport_rs485, "ISKBoard2PC-RS485", strlen("ISKBoard2PC-RS485"));
    }
cleanup:
    rs485_term(comport_rs485);
    return rv;
}
int can_test(can_t *pcan)
{
    char                rx_data_buf[8] = { 0 };
    char                 test_data_buf[8] = {0x01, 0x02, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    int                 rv = 0;
    if( !pcan )
    {
        //printf("%s() CAN open failed\r\n", __func__);
        return -2;
    }
    if(can_recv(pcan, rx_data_buf, sizeof(rx_data_buf), BLOCK_TIME) > 0)
    {
#if 0    //echo CAN recv 8bytes data
        printf("CAN RX DATA:");
        for(int i=0; i<sizeof(rx_data_buf); i++)
        {
            printf("0x%x ", rx_data_buf[i]);
        }
        printf("\r\n");
#endif
        if( !memcmp(test_data_buf, rx_data_buf, sizeof(test_data_buf)) )
        {
            can_send(pcan, test_data_buf, sizeof(test_data_buf));
        }else
        {
            rv = -3;
            goto cleanup;
        }
    }else
    {
        rv = -4;
        goto cleanup;
    }
cleanup:
    return rv;
}
int test_mikrobus(void)
{
    int                 i = 0, rv=0;
    int                 failed = 0;
    for(i=0; i<MIKROBUS_PIN_GROUP; i++)
    {
        /* Set pin as output/input mode */
        set_gpio_mode(mikrobus_pins[i][0], PIN_OUTPUT);
        set_gpio_mode(mikrobus_pins[i][1], PIN_INPUT);
        HAL_GPIO_WritePin(mikrobus_pins[i][0].group, mikrobus_pins[i][0].pin, GPIO_PIN_SET);
        if( GPIO_PIN_SET != HAL_GPIO_ReadPin(mikrobus_pins[i][1].group, mikrobus_pins[i][1].pin) )
        {
            failed = 1;
            break;
        }
        HAL_GPIO_WritePin(mikrobus_pins[i][0].group, mikrobus_pins[i][0].pin, GPIO_PIN_RESET);
        if( GPIO_PIN_RESET != HAL_GPIO_ReadPin(mikrobus_pins[i][1].group, mikrobus_pins[i][1].pin) )
        {
            failed = 1;
            break;
        }
        /* Set pin as output mode */
        set_gpio_mode(mikrobus_pins[i][1], PIN_OUTPUT);
        set_gpio_mode(mikrobus_pins[i][0], PIN_INPUT);
        HAL_GPIO_WritePin(mikrobus_pins[i][1].group, mikrobus_pins[i][1].pin, GPIO_PIN_SET);
        if( GPIO_PIN_SET != HAL_GPIO_ReadPin(mikrobus_pins[i][0].group, mikrobus_pins[i][0].pin) )
        {
            failed = 1;
            break;
        }
        HAL_GPIO_WritePin(mikrobus_pins[i][1].group, mikrobus_pins[i][1].pin, GPIO_PIN_RESET);
        if( GPIO_PIN_RESET != HAL_GPIO_ReadPin(mikrobus_pins[i][0].group, mikrobus_pins[i][0].pin) )
        {
            failed = 1;
            break;
        }
        printf("MikroBUS %4s<->%4s test [OKAY]\r\n", mikrobus_pins[i][0].name, mikrobus_pins[i][1].name);
    }
    if( failed )
    {
        printf("MikroBUS %4s<->%4s test [FAIL]\r\n", mikrobus_pins[i][0].name, mikrobus_pins[i][1].name);
        rv = -1;
        goto cleanup;
    }
    if( comport_test(&huart3) < 0 )
        printf("MikroBUS UART test        [FAIL]\r\n");
    else
        printf("MikroBUS UART test        [OKAY]\r\n");
cleanup:
    if( rv )
        oled_show("MikroBUS [FAIL]");
    else
        oled_show("MikroBUS [OK]");
    printf("\r\n");
    return 0;
}
int test_led(void)
{
    oled_show("LED [TEST]");
    printf("RGB Led                   [TEST]\r\n");
    blink_led(LedRed, 200);
    blink_led(LedGreen, 200);
    blink_led(LedBlue, 200);
    printf("Strip Lights              [TEST]\r\n");
    ws2812b_blink();
    printf("\r\n");
    return 0;
}
int test_spiflash(void)
{
    int              rv;
    char             oledstr[32] = {0};
    rv = w25q_Init();
    printf("SPI Flash W25Q32     test [%s]\r\n", rv?"FAIL":"OKAY");
    snprintf(oledstr, sizeof(oledstr), "W25Q: %s", rv?"FAIL":"OK");
    oled_show(oledstr);
    printf("\r\n");
    return 0;
}
int test_wifi(void)
{
    static int         init = 0;
    static comport_t  *comport = NULL;
    int                rv;
    char               oledstr[32] = {0};
    char               version[256] = {0};
    if( !init )
    {
        comport = comport_open(&huart2);
        if( !comport )
            return -1;
        esp32_hwreset(comport);
        esp32_set_echo(comport, DISABLE);
        rv = esp32_get_firmware(comport, version, sizeof(version));
        if( rv < 0)
        {
            printf("Query ESP32 firmware version failed: %d\r\n", rv);
            return rv;
        }
        printf("ESP32 firmware version:\r\n%s\r\n", version);
        init = 1;
    }
    rv = send_atcmd_check_ok(comport, "AT", 500);
    printf("WiFi module AT test       [%s]\r\n", rv?"FAIL":"OKAY");
    snprintf(oledstr, sizeof(oledstr), "WiFi: %s", rv?"FAIL":"OK");
    oled_show(oledstr);
    printf("\r\n");
    return 0;
}
int test_adc(void)
{
    char             oledstr[32] = {0};
    uint32_t         lux, noisy;
      adc_sample_lux_noisy(&lux, &noisy);
      printf("Lux: %lu Noisy: %lu\r\n", lux, noisy);
      printf("ADC(Lux/Noisy) test       [OKAY]\r\n");
      snprintf(oledstr, sizeof(oledstr), "lux:%lu db:%lu", lux, noisy);
      oled_show(oledstr);
      printf("\r\n");
      return 0;
}
int test_ds18b20(void)
{
    int              rv;
    float            temperature_f = 0.0;
    char             oledstr[32] = {0};
    rv = ds18b20_sample(&temperature_f);
    if( rv < 0 )
    {
        printf("DS18B20 test              [FAIL]\r\n");
          oled_show("DS18B20: [FAIL]");
        return -1;
    }
    printf("DS18B20 sample temperature: %.3f\'C\r\n", temperature_f);
    printf("DS18B20 test              [OKAY]\r\n");
      snprintf(oledstr, sizeof(oledstr), "DS18B20: %.3f", temperature_f);
      oled_show(oledstr);
      printf("\r\n");
      return 0;
}
int test_sht20(void)
{
    uint32_t         TrH, temperature, humdity;
    char             oledstr[32] = {0};
    TrH = sht20_sample_TrH(&temperature, &humdity);
    if( TRH_FAIL_VAL == TrH)
    {
        printf("SHT20 test                [FAIL]\r\n");
          oled_show("SHT20: [FAIL]");
        return -1;
    }
    printf("SHT20 sample temperature: %lu.%02lu\'C humidity: %lu.%02lu%%\r\n",
            temperature/100, temperature%100, humdity/100, humdity%100);
    printf("SHT20 test                [OKAY]\r\n");
    snprintf(oledstr, sizeof(oledstr), "SHT20: %lu.%02lu\'C", temperature/100, temperature%100);
      oled_show(oledstr);
    snprintf(oledstr, sizeof(oledstr), "SHT20: %lu.%02lu%%", humdity/100, humdity%100);
      oled_show(oledstr);
      printf("\r\n");
      return 0;
}
int test_rtc(void)
{
    char             oledstr[32] = {0};
    rtc_time_t       tm;
    if( get_rtc_time(&tm) < 0 )
        return -1;
    printf("RTC: %04d-%02d-%02d %02d:%02d:%02d %s\r\n", tm.tm_year, tm.tm_mon, tm.tm_mday,
        tm.tm_hour, tm.tm_min, tm.tm_sec, weekday[tm.tm_wday]);
    printf("RTC ISL1208 test          [OKAY]\r\n");
    snprintf(oledstr, sizeof(oledstr), "RTC: %04d-%02d-%02d", tm.tm_year, tm.tm_mon, tm.tm_mday);
      oled_show(oledstr);
    snprintf(oledstr, sizeof(oledstr), "RTC: %02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
      oled_show(oledstr);
      printf("\r\n");
    return 0;
}
int test_usart3(void)
{
    printf("Please switch USART3 to RS232.\r\n");
    if( comport_test(&huart3) < 0 )
    {
        printf("USART3 RS232 test         [FAIL]\r\n");
        oled_show("RS232  [FAIL]");
    }
    else
    {
        printf("USART3 RS232 test         [OKAY]\r\n");
        oled_show("RS232  [OK]");
    }
      printf("\r\n");
      return 0;
}
int test_can(void)
{
    printf("Please send {0x01, 0x02, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F} CAN frame data in PC.\r\n");
    if( can_test(&can) < 0 )
    {
        printf("CAN test                  [FAIL]\r\n");
        oled_show("CAN  [FAIL]");
    }
    else
    {
        printf("CAN test                  [OKAY]\r\n");
        oled_show("CAN  [OK]");
    }
      printf("\r\n");
      return 0;
}
int test_rs485(void)
{
    printf("Please send {PC2ISKBoard-RS485} rs485 data in PC.\r\n");
    if( rs485_test(&hlpuart1) < 0 )
    {
        printf("RS485 test                [FAIL]\r\n");
        oled_show("RS485  [FAIL]");
    }
    else
    {
        printf("RS485 test                [OKAY]\r\n");
        oled_show("RS485  [OK]");
    }
      printf("\r\n");
      return 0;
}
/* USER CODE END 4 */
/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
Production/ISKBoard_QCTester/Core/Src/spi.c
New file
@@ -0,0 +1,121 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    spi.c
  * @brief   This file provides code for the configuration
  *          of the SPI instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "spi.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
SPI_HandleTypeDef hspi1;
/* SPI1 init function */
void MX_SPI1_Init(void)
{
  /* USER CODE BEGIN SPI1_Init 0 */
  /* USER CODE END SPI1_Init 0 */
  /* USER CODE BEGIN SPI1_Init 1 */
  /* USER CODE END SPI1_Init 1 */
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */
  /* USER CODE END SPI1_Init 2 */
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(spiHandle->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspInit 0 */
  /* USER CODE END SPI1_MspInit 0 */
    /* SPI1 clock enable */
    __HAL_RCC_SPI1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**SPI1 GPIO Configuration
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  /* USER CODE BEGIN SPI1_MspInit 1 */
  /* USER CODE END SPI1_MspInit 1 */
  }
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
  if(spiHandle->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspDeInit 0 */
  /* USER CODE END SPI1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_SPI1_CLK_DISABLE();
    /**SPI1 GPIO Configuration
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
  /* USER CODE BEGIN SPI1_MspDeInit 1 */
  /* USER CODE END SPI1_MspDeInit 1 */
  }
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Production/ISKBoard_QCTester/Core/Src/stm32l4xx_hal_msp.c
New file
@@ -0,0 +1,81 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file         stm32l4xx_hal_msp.c
  * @brief        This file provides code for the MSP Initialization
  *               and de-Initialization codes.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
  * Initializes the Global MSP.
  */
void HAL_MspInit(void)
{
  /* USER CODE BEGIN MspInit 0 */
  /* USER CODE END MspInit 0 */
  __HAL_RCC_SYSCFG_CLK_ENABLE();
  __HAL_RCC_PWR_CLK_ENABLE();
  /* System interrupt init*/
  /* USER CODE BEGIN MspInit 1 */
  /* USER CODE END MspInit 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Production/ISKBoard_QCTester/Core/Src/stm32l4xx_it.c
New file
@@ -0,0 +1,293 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32l4xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan1;
extern UART_HandleTypeDef hlpuart1;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/*           Cortex-M4 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable interrupt.
  */
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */
  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}
/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */
  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}
/**
  * @brief This function handles Prefetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */
  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}
/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */
  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}
/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */
  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */
  /* USER CODE END SVCall_IRQn 1 */
}
/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */
  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */
  /* USER CODE END DebugMonitor_IRQn 1 */
}
/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */
  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */
  /* USER CODE END PendSV_IRQn 1 */
}
/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  /* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32l4xx.s).                    */
/******************************************************************************/
/**
  * @brief This function handles CAN1 RX0 interrupt.
  */
void CAN1_RX0_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_RX0_IRQn 0 */
  /* USER CODE END CAN1_RX0_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_RX0_IRQn 1 */
  /* USER CODE END CAN1_RX0_IRQn 1 */
}
/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  /* USER CODE END USART1_IRQn 1 */
}
/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
  /* USER CODE END USART2_IRQn 1 */
}
/**
  * @brief This function handles USART3 global interrupt.
  */
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
  /* USER CODE END USART3_IRQn 1 */
}
/**
  * @brief This function handles EXTI line[15:10] interrupts.
  */
void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
  /* USER CODE END EXTI15_10_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(Key1_Pin);
  HAL_GPIO_EXTI_IRQHandler(Key2_Pin);
  HAL_GPIO_EXTI_IRQHandler(Key3_Pin);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */
  /* USER CODE END EXTI15_10_IRQn 1 */
}
/**
  * @brief This function handles LPUART1 global interrupt.
  */
void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&hlpuart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */
  /* USER CODE END LPUART1_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Production/ISKBoard_QCTester/Core/Src/syscalls.c
New file
@@ -0,0 +1,176 @@
/**
 ******************************************************************************
 * @file      syscalls.c
 * @author    Auto-generated by STM32CubeIDE
 * @brief     STM32CubeIDE Minimal System calls file
 *
 *            For more information about which c-functions
 *            need which of these lowlevel functions
 *            please consult the Newlib libc-manual
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2020-2022 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* Includes */
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
/* Variables */
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));
char *__env[1] = { 0 };
char **environ = __env;
/* Functions */
void initialise_monitor_handles()
{
}
int _getpid(void)
{
  return 1;
}
int _kill(int pid, int sig)
{
  (void)pid;
  (void)sig;
  errno = EINVAL;
  return -1;
}
void _exit (int status)
{
  _kill(status, -1);
  while (1) {}    /* Make sure we hang here */
}
__attribute__((weak)) int _read(int file, char *ptr, int len)
{
  (void)file;
  int DataIdx;
  for (DataIdx = 0; DataIdx < len; DataIdx++)
  {
    *ptr++ = __io_getchar();
  }
  return len;
}
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
  (void)file;
  int DataIdx;
  for (DataIdx = 0; DataIdx < len; DataIdx++)
  {
    __io_putchar(*ptr++);
  }
  return len;
}
int _close(int file)
{
  (void)file;
  return -1;
}
int _fstat(int file, struct stat *st)
{
  (void)file;
  st->st_mode = S_IFCHR;
  return 0;
}
int _isatty(int file)
{
  (void)file;
  return 1;
}
int _lseek(int file, int ptr, int dir)
{
  (void)file;
  (void)ptr;
  (void)dir;
  return 0;
}
int _open(char *path, int flags, ...)
{
  (void)path;
  (void)flags;
  /* Pretend like we always fail */
  return -1;
}
int _wait(int *status)
{
  (void)status;
  errno = ECHILD;
  return -1;
}
int _unlink(char *name)
{
  (void)name;
  errno = ENOENT;
  return -1;
}
int _times(struct tms *buf)
{
  (void)buf;
  return -1;
}
int _stat(char *file, struct stat *st)
{
  (void)file;
  st->st_mode = S_IFCHR;
  return 0;
}
int _link(char *old, char *new)
{
  (void)old;
  (void)new;
  errno = EMLINK;
  return -1;
}
int _fork(void)
{
  errno = EAGAIN;
  return -1;
}
int _execve(char *name, char **argv, char **env)
{
  (void)name;
  (void)argv;
  (void)env;
  errno = ENOMEM;
  return -1;
}
Production/ISKBoard_QCTester/Core/Src/sysmem.c
New file
@@ -0,0 +1,79 @@
/**
 ******************************************************************************
 * @file      sysmem.c
 * @author    Generated by STM32CubeIDE
 * @brief     STM32CubeIDE System Memory calls file
 *
 *            For more information about which C functions
 *            need which of these lowlevel functions
 *            please consult the newlib libc manual
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2022 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* Includes */
#include <errno.h>
#include <stdint.h>
/**
 * Pointer to the current high watermark of the heap usage
 */
static uint8_t *__sbrk_heap_end = NULL;
/**
 * @brief _sbrk() allocates memory to the newlib heap and is used by malloc
 *        and others from the C library
 *
 * @verbatim
 * ############################################################################
 * #  .data  #  .bss  #       newlib heap       #          MSP stack          #
 * #         #        #                         # Reserved by _Min_Stack_Size #
 * ############################################################################
 * ^-- RAM start      ^-- _end                             _estack, RAM end --^
 * @endverbatim
 *
 * This implementation starts allocating at the '_end' linker symbol
 * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
 * The implementation considers '_estack' linker symbol to be RAM end
 * NOTE: If the MSP stack, at any point during execution, grows larger than the
 * reserved size, please increase the '_Min_Stack_Size'.
 *
 * @param incr Memory size
 * @return Pointer to allocated memory
 */
void *_sbrk(ptrdiff_t incr)
{
  extern uint8_t _end; /* Symbol defined in the linker script */
  extern uint8_t _estack; /* Symbol defined in the linker script */
  extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
  const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
  const uint8_t *max_heap = (uint8_t *)stack_limit;
  uint8_t *prev_heap_end;
  /* Initialize heap end at first call */
  if (NULL == __sbrk_heap_end)
  {
    __sbrk_heap_end = &_end;
  }
  /* Protect heap from growing into the reserved MSP stack */
  if (__sbrk_heap_end + incr > max_heap)
  {
    errno = ENOMEM;
    return (void *)-1;
  }
  prev_heap_end = __sbrk_heap_end;
  __sbrk_heap_end += incr;
  return (void *)prev_heap_end;
}
Production/ISKBoard_QCTester/Core/Src/system_stm32l4xx.c
New file
@@ -0,0 +1,332 @@
/**
  ******************************************************************************
  * @file    system_stm32l4xx.c
  * @author  MCD Application Team
  * @brief   CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
  *
  *   This file provides two functions and one global variable to be called from
  *   user application:
  *      - SystemInit(): This function is called at startup just after reset and
  *                      before branch to main program. This call is made inside
  *                      the "startup_stm32l4xx.s" file.
  *
  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
  *                                  by the user application to setup the SysTick
  *                                  timer or configure other parameters.
  *
  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
  *                                 be called whenever the core clock is changed
  *                                 during program execution.
  *
  *   After each device reset the MSI (4 MHz) is used as system clock source.
  *   Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to
  *   configure the system clock before to branch to main program.
  *
  *   This file configures the system clock as follows:
  *=============================================================================
  *-----------------------------------------------------------------------------
  *        System Clock source                    | MSI
  *-----------------------------------------------------------------------------
  *        SYSCLK(Hz)                             | 4000000
  *-----------------------------------------------------------------------------
  *        HCLK(Hz)                               | 4000000
  *-----------------------------------------------------------------------------
  *        AHB Prescaler                          | 1
  *-----------------------------------------------------------------------------
  *        APB1 Prescaler                         | 1
  *-----------------------------------------------------------------------------
  *        APB2 Prescaler                         | 1
  *-----------------------------------------------------------------------------
  *        PLL_M                                  | 1
  *-----------------------------------------------------------------------------
  *        PLL_N                                  | 8
  *-----------------------------------------------------------------------------
  *        PLL_P                                  | 7
  *-----------------------------------------------------------------------------
  *        PLL_Q                                  | 2
  *-----------------------------------------------------------------------------
  *        PLL_R                                  | 2
  *-----------------------------------------------------------------------------
  *        PLLSAI1_P                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI1_Q                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI1_R                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI2_P                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI2_Q                              | NA
  *-----------------------------------------------------------------------------
  *        PLLSAI2_R                              | NA
  *-----------------------------------------------------------------------------
  *        Require 48MHz for USB OTG FS,          | Disabled
  *        SDIO and RNG clock                     |
  *-----------------------------------------------------------------------------
  *=============================================================================
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/** @addtogroup CMSIS
  * @{
  */
/** @addtogroup stm32l4xx_system
  * @{
  */
/** @addtogroup STM32L4xx_System_Private_Includes
  * @{
  */
#include "stm32l4xx.h"
/**
  * @}
  */
/** @addtogroup STM32L4xx_System_Private_TypesDefinitions
  * @{
  */
/**
  * @}
  */
/** @addtogroup STM32L4xx_System_Private_Defines
  * @{
  */
#if !defined  (HSE_VALUE)
  #define HSE_VALUE    8000000U  /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined  (MSI_VALUE)
  #define MSI_VALUE    4000000U  /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
#if !defined  (HSI_VALUE)
  #define HSI_VALUE    16000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/* Note: Following vector table addresses must be defined in line with linker
         configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
     anywhere in Flash or Sram, else the vector table is kept at the automatic
     remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM1_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
/**
  * @}
  */
/** @addtogroup STM32L4xx_System_Private_Macros
  * @{
  */
/**
  * @}
  */
/** @addtogroup STM32L4xx_System_Private_Variables
  * @{
  */
  /* The SystemCoreClock variable is updated in three ways:
      1) by calling CMSIS function SystemCoreClockUpdate()
      2) by calling HAL API function HAL_RCC_GetHCLKFreq()
      3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
         Note: If you use this function to configure the system clock; then there
               is no need to call the 2 first functions listed above, since SystemCoreClock
               variable is updated automatically.
  */
  uint32_t SystemCoreClock = 4000000U;
  const uint8_t  AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
  const uint8_t  APBPrescTable[8] =  {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
  const uint32_t MSIRangeTable[12] = {100000U,   200000U,   400000U,   800000U,  1000000U,  2000000U, \
                                      4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U};
/**
  * @}
  */
/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes
  * @{
  */
/**
  * @}
  */
/** @addtogroup STM32L4xx_System_Private_Functions
  * @{
  */
/**
  * @brief  Setup the microcontroller system.
  * @retval None
  */
void SystemInit(void)
{
#if defined(USER_VECT_TAB_ADDRESS)
  /* Configure the Vector Table location -------------------------------------*/
  SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
#endif
  /* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  SCB->CPACR |= ((3UL << 20U)|(3UL << 22U));  /* set CP10 and CP11 Full Access */
#endif
}
/**
  * @brief  Update SystemCoreClock variable according to Clock Register Values.
  *         The SystemCoreClock variable contains the core clock (HCLK), it can
  *         be used by the user application to setup the SysTick timer or configure
  *         other parameters.
  *
  * @note   Each time the core clock (HCLK) changes, this function must be called
  *         to update SystemCoreClock variable value. Otherwise, any configuration
  *         based on this variable will be incorrect.
  *
  * @note   - The system frequency computed by this function is not the real
  *           frequency in the chip. It is calculated based on the predefined
  *           constant and the selected clock source:
  *
  *           - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
  *
  *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
  *
  *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
  *
  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
  *             or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
  *
  *         (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  *             4 MHz) but the real value may vary depending on the variations
  *             in voltage and temperature.
  *
  *         (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  *              16 MHz) but the real value may vary depending on the variations
  *              in voltage and temperature.
  *
  *         (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  *              8 MHz), user has to ensure that HSE_VALUE is same as the real
  *              frequency of the crystal used. Otherwise, this function may
  *              have wrong result.
  *
  *         - The result of this function could be not correct when using fractional
  *           value for HSE crystal.
  *
  * @retval None
  */
void SystemCoreClockUpdate(void)
{
  uint32_t tmp, msirange, pllvco, pllsource, pllm, pllr;
  /* Get MSI Range frequency--------------------------------------------------*/
  if ((RCC->CR & RCC_CR_MSIRGSEL) == 0U)
  { /* MSISRANGE from RCC_CSR applies */
    msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U;
  }
  else
  { /* MSIRANGE from RCC_CR applies */
    msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U;
  }
  /*MSI frequency range in HZ*/
  msirange = MSIRangeTable[msirange];
  /* Get SYSCLK source -------------------------------------------------------*/
  switch (RCC->CFGR & RCC_CFGR_SWS)
  {
    case 0x00:  /* MSI used as system clock source */
      SystemCoreClock = msirange;
      break;
    case 0x04:  /* HSI used as system clock source */
      SystemCoreClock = HSI_VALUE;
      break;
    case 0x08:  /* HSE used as system clock source */
      SystemCoreClock = HSE_VALUE;
      break;
    case 0x0C:  /* PLL used as system clock  source */
      /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
         SYSCLK = PLL_VCO / PLLR
         */
      pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
      pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ;
      switch (pllsource)
      {
        case 0x02:  /* HSI used as PLL clock source */
          pllvco = (HSI_VALUE / pllm);
          break;
        case 0x03:  /* HSE used as PLL clock source */
          pllvco = (HSE_VALUE / pllm);
          break;
        default:    /* MSI used as PLL clock source */
          pllvco = (msirange / pllm);
          break;
      }
      pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U);
      pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U;
      SystemCoreClock = pllvco/pllr;
      break;
    default:
      SystemCoreClock = msirange;
      break;
  }
  /* Compute HCLK clock frequency --------------------------------------------*/
  /* Get HCLK prescaler */
  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
  /* HCLK clock frequency */
  SystemCoreClock >>= tmp;
}
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Production/ISKBoard_QCTester/Core/Src/tim.c
New file
@@ -0,0 +1,221 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    tim.c
  * @brief   This file provides code for the configuration
  *          of the TIM instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "tim.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim6;
/* TIM1 init function */
void MX_TIM1_Init(void)
{
  /* USER CODE BEGIN TIM1_Init 0 */
  /* USER CODE END TIM1_Init 0 */
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
  /* USER CODE BEGIN TIM1_Init 1 */
  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 80-1;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 370-1;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 185;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.BreakFilter = 0;
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */
  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);
}
/* TIM6 init function */
void MX_TIM6_Init(void)
{
  /* USER CODE BEGIN TIM6_Init 0 */
  /* USER CODE END TIM6_Init 0 */
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  /* USER CODE BEGIN TIM6_Init 1 */
  /* USER CODE END TIM6_Init 1 */
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 80-1;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 1;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM6_Init 2 */
  /* USER CODE END TIM6_Init 2 */
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
{
  if(tim_pwmHandle->Instance==TIM1)
  {
  /* USER CODE BEGIN TIM1_MspInit 0 */
  /* USER CODE END TIM1_MspInit 0 */
    /* TIM1 clock enable */
    __HAL_RCC_TIM1_CLK_ENABLE();
  /* USER CODE BEGIN TIM1_MspInit 1 */
  /* USER CODE END TIM1_MspInit 1 */
  }
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
  if(tim_baseHandle->Instance==TIM6)
  {
  /* USER CODE BEGIN TIM6_MspInit 0 */
  /* USER CODE END TIM6_MspInit 0 */
    /* TIM6 clock enable */
    __HAL_RCC_TIM6_CLK_ENABLE();
  /* USER CODE BEGIN TIM6_MspInit 1 */
  /* USER CODE END TIM6_MspInit 1 */
  }
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(timHandle->Instance==TIM1)
  {
  /* USER CODE BEGIN TIM1_MspPostInit 0 */
  /* USER CODE END TIM1_MspPostInit 0 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**TIM1 GPIO Configuration
    PA11     ------> TIM1_CH4
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  /* USER CODE BEGIN TIM1_MspPostInit 1 */
  /* USER CODE END TIM1_MspPostInit 1 */
  }
}
void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle)
{
  if(tim_pwmHandle->Instance==TIM1)
  {
  /* USER CODE BEGIN TIM1_MspDeInit 0 */
  /* USER CODE END TIM1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM1_CLK_DISABLE();
  /* USER CODE BEGIN TIM1_MspDeInit 1 */
  /* USER CODE END TIM1_MspDeInit 1 */
  }
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
  if(tim_baseHandle->Instance==TIM6)
  {
  /* USER CODE BEGIN TIM6_MspDeInit 0 */
  /* USER CODE END TIM6_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM6_CLK_DISABLE();
  /* USER CODE BEGIN TIM6_MspDeInit 1 */
  /* USER CODE END TIM6_MspDeInit 1 */
  }
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Production/ISKBoard_QCTester/Core/Src/usart.c
New file
@@ -0,0 +1,409 @@
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    usart.c
  * @brief   This file provides code for the configuration
  *          of the USART instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
/* USER CODE BEGIN 0 */
#include "comport.h"
uint8_t     g_uart1_rxch;
uint8_t     uart2_rxch;
uint8_t     uart2_rxbuf[COMM_RXBUFSIZE];
uint8_t     uart3_rxch;
uint8_t     uart3_rxbuf[COMM_RXBUFSIZE];
uint8_t     lpuart1_rxch;
uint8_t     lpuart1_rxbuf[COMM_RXBUFSIZE];
/* USER CODE END 0 */
UART_HandleTypeDef hlpuart1;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;
/* LPUART1 init function */
void MX_LPUART1_UART_Init(void)
{
  /* USER CODE BEGIN LPUART1_Init 0 */
  /* USER CODE END LPUART1_Init 0 */
  /* USER CODE BEGIN LPUART1_Init 1 */
  /* USER CODE END LPUART1_Init 1 */
  hlpuart1.Instance = LPUART1;
  hlpuart1.Init.BaudRate = 115200;
  hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
  hlpuart1.Init.StopBits = UART_STOPBITS_1;
  hlpuart1.Init.Parity = UART_PARITY_NONE;
  hlpuart1.Init.Mode = UART_MODE_TX_RX;
  hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LPUART1_Init 2 */
  comport_init(&hlpuart1 , &lpuart1_rxch, lpuart1_rxbuf, sizeof(lpuart1_rxbuf));
  HAL_UART_Receive_IT(&hlpuart1 , &lpuart1_rxch, 1);
  /* USER CODE END LPUART1_Init 2 */
}
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
  /* USER CODE BEGIN USART1_Init 0 */
  /* USER CODE END USART1_Init 0 */
  /* USER CODE BEGIN USART1_Init 1 */
  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
  HAL_UART_Receive_IT(&huart1 , &g_uart1_rxch, 1);
  /* USER CODE END USART1_Init 2 */
}
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
  /* USER CODE BEGIN USART2_Init 0 */
  /* USER CODE END USART2_Init 0 */
  /* USER CODE BEGIN USART2_Init 1 */
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
  comport_init(&huart2 , &uart2_rxch, uart2_rxbuf, sizeof(uart2_rxbuf));
  HAL_UART_Receive_IT(&huart2 , &uart2_rxch, 1);
  /* USER CODE END USART2_Init 2 */
}
/* USART3 init function */
void MX_USART3_UART_Init(void)
{
  /* USER CODE BEGIN USART3_Init 0 */
  /* USER CODE END USART3_Init 0 */
  /* USER CODE BEGIN USART3_Init 1 */
  /* USER CODE END USART3_Init 1 */
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART3_Init 2 */
  comport_init(&huart3 , &uart3_rxch, uart3_rxbuf, sizeof(uart3_rxbuf));
  HAL_UART_Receive_IT(&huart3 , &uart3_rxch, 1);
  /* USER CODE END USART3_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(uartHandle->Instance==LPUART1)
  {
  /* USER CODE BEGIN LPUART1_MspInit 0 */
  /* USER CODE END LPUART1_MspInit 0 */
  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
    PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
    /* LPUART1 clock enable */
    __HAL_RCC_LPUART1_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**LPUART1 GPIO Configuration
    PC0     ------> LPUART1_RX
    PC1     ------> LPUART1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    /* LPUART1 interrupt Init */
    HAL_NVIC_SetPriority(LPUART1_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(LPUART1_IRQn);
  /* USER CODE BEGIN LPUART1_MspInit 1 */
  /* USER CODE END LPUART1_MspInit 1 */
  }
  else if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */
  /* USER CODE END USART1_MspInit 0 */
  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
    PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */
  /* USER CODE END USART1_MspInit 1 */
  }
  else if(uartHandle->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspInit 0 */
  /* USER CODE END USART2_MspInit 0 */
  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
    PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
    /* USART2 clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspInit 1 */
  /* USER CODE END USART2_MspInit 1 */
  }
  else if(uartHandle->Instance==USART3)
  {
  /* USER CODE BEGIN USART3_MspInit 0 */
  /* USER CODE END USART3_MspInit 0 */
  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
    PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
    /* USART3 clock enable */
    __HAL_RCC_USART3_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**USART3 GPIO Configuration
    PC4     ------> USART3_TX
    PC5     ------> USART3_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    /* USART3 interrupt Init */
    HAL_NVIC_SetPriority(USART3_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(USART3_IRQn);
  /* USER CODE BEGIN USART3_MspInit 1 */
  /* USER CODE END USART3_MspInit 1 */
  }
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
  if(uartHandle->Instance==LPUART1)
  {
  /* USER CODE BEGIN LPUART1_MspDeInit 0 */
  /* USER CODE END LPUART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_LPUART1_CLK_DISABLE();
    /**LPUART1 GPIO Configuration
    PC0     ------> LPUART1_RX
    PC1     ------> LPUART1_TX
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1);
    /* LPUART1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(LPUART1_IRQn);
  /* USER CODE BEGIN LPUART1_MspDeInit 1 */
  /* USER CODE END LPUART1_MspDeInit 1 */
  }
  else if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */
  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
    /* USART1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspDeInit 1 */
  /* USER CODE END USART1_MspDeInit 1 */
  }
  else if(uartHandle->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspDeInit 0 */
  /* USER CODE END USART2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART2_CLK_DISABLE();
    /**USART2 GPIO Configuration
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
    /* USART2 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspDeInit 1 */
  /* USER CODE END USART2_MspDeInit 1 */
  }
  else if(uartHandle->Instance==USART3)
  {
  /* USER CODE BEGIN USART3_MspDeInit 0 */
  /* USER CODE END USART3_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART3_CLK_DISABLE();
    /**USART3 GPIO Configuration
    PC4     ------> USART3_TX
    PC5     ------> USART3_RX
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4|GPIO_PIN_5);
    /* USART3 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART3_IRQn);
  /* USER CODE BEGIN USART3_MspDeInit 1 */
  /* USER CODE END USART3_MspDeInit 1 */
  }
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Production/ISKBoard_QCTester/Core/Startup/startup_stm32l431rctx.s
New file
@@ -0,0 +1,461 @@
/**
  ******************************************************************************
  * @file      startup_stm32l431xx.s
  * @author    MCD Application Team
  * @brief     STM32L431xx devices vector table for GCC toolchain.
  *            This module performs:
  *                - Set the initial SP
  *                - Set the initial PC == Reset_Handler,
  *                - Set the vector table entries with the exceptions ISR address,
  *                - Configure the clock system
  *                - Branches to main in the C library (which eventually
  *                  calls main()).
  *            After Reset the Cortex-M4 processor is in Thread mode,
  *            priority is Privileged, and the Stack is set to Main.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
  .syntax unified
    .cpu cortex-m4
    .fpu softvfp
    .thumb
.global    g_pfnVectors
.global    Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word    _sidata
/* start address for the .data section. defined in linker script */
.word    _sdata
/* end address for the .data section. defined in linker script */
.word    _edata
/* start address for the .bss section. defined in linker script */
.word    _sbss
/* end address for the .bss section. defined in linker script */
.word    _ebss
.equ  BootRAM,        0xF1E0F85F
/**
 * @brief  This is the code that gets called when the processor first
 *          starts execution following a reset event. Only the absolutely
 *          necessary set is performed, after which the application
 *          supplied main() routine is called.
 * @param  None
 * @retval : None
*/
    .section    .text.Reset_Handler
    .weak    Reset_Handler
    .type    Reset_Handler, %function
Reset_Handler:
  ldr   sp, =_estack    /* Set stack pointer */
/* Call the clock system initialization function.*/
    bl  SystemInit
/* Copy the data segment initializers from flash to SRAM */
  ldr r0, =_sdata
  ldr r1, =_edata
  ldr r2, =_sidata
  movs r3, #0
  b LoopCopyDataInit
CopyDataInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4
LoopCopyDataInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyDataInit
/* Zero fill the bss segment. */
  ldr r2, =_sbss
  ldr r4, =_ebss
  movs r3, #0
  b LoopFillZerobss
FillZerobss:
  str  r3, [r2]
  adds r2, r2, #4
LoopFillZerobss:
  cmp r2, r4
  bcc FillZerobss
/* Call static constructors */
    bl __libc_init_array
/* Call the application's entry point.*/
    bl    main
LoopForever:
    b LoopForever
.size    Reset_Handler, .-Reset_Handler
/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 *
 * @param  None
 * @retval : None
*/
    .section    .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
    b    Infinite_Loop
    .size    Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex-M4.  Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
     .section    .isr_vector,"a",%progbits
    .type    g_pfnVectors, %object
    .size    g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
    .word    _estack
    .word    Reset_Handler
    .word    NMI_Handler
    .word    HardFault_Handler
    .word    MemManage_Handler
    .word    BusFault_Handler
    .word    UsageFault_Handler
    .word    0
    .word    0
    .word    0
    .word    0
    .word    SVC_Handler
    .word    DebugMon_Handler
    .word    0
    .word    PendSV_Handler
    .word    SysTick_Handler
    .word    WWDG_IRQHandler
    .word    PVD_PVM_IRQHandler
    .word    TAMP_STAMP_IRQHandler
    .word    RTC_WKUP_IRQHandler
    .word    FLASH_IRQHandler
    .word    RCC_IRQHandler
    .word    EXTI0_IRQHandler
    .word    EXTI1_IRQHandler
    .word    EXTI2_IRQHandler
    .word    EXTI3_IRQHandler
    .word    EXTI4_IRQHandler
    .word    DMA1_Channel1_IRQHandler
    .word    DMA1_Channel2_IRQHandler
    .word    DMA1_Channel3_IRQHandler
    .word    DMA1_Channel4_IRQHandler
    .word    DMA1_Channel5_IRQHandler
    .word    DMA1_Channel6_IRQHandler
    .word    DMA1_Channel7_IRQHandler
    .word    ADC1_IRQHandler
    .word    CAN1_TX_IRQHandler
    .word    CAN1_RX0_IRQHandler
    .word    CAN1_RX1_IRQHandler
    .word    CAN1_SCE_IRQHandler
    .word    EXTI9_5_IRQHandler
    .word    TIM1_BRK_TIM15_IRQHandler
    .word    TIM1_UP_TIM16_IRQHandler
    .word    TIM1_TRG_COM_IRQHandler
    .word    TIM1_CC_IRQHandler
    .word    TIM2_IRQHandler
    .word    0
    .word    0
    .word    I2C1_EV_IRQHandler
    .word    I2C1_ER_IRQHandler
    .word    I2C2_EV_IRQHandler
    .word    I2C2_ER_IRQHandler
    .word    SPI1_IRQHandler
    .word    SPI2_IRQHandler
    .word    USART1_IRQHandler
    .word    USART2_IRQHandler
    .word    USART3_IRQHandler
    .word    EXTI15_10_IRQHandler
    .word    RTC_Alarm_IRQHandler
    .word    0
    .word    0
    .word    0
    .word    0
    .word    0
    .word    0
    .word    0
    .word    SDMMC1_IRQHandler
    .word    0
    .word    SPI3_IRQHandler
    .word    0
    .word    0
    .word    TIM6_DAC_IRQHandler
    .word    TIM7_IRQHandler
    .word    DMA2_Channel1_IRQHandler
    .word    DMA2_Channel2_IRQHandler
    .word    DMA2_Channel3_IRQHandler
    .word    DMA2_Channel4_IRQHandler
    .word    DMA2_Channel5_IRQHandler
    .word    0
    .word    0
    .word    0
    .word    COMP_IRQHandler
    .word    LPTIM1_IRQHandler
    .word    LPTIM2_IRQHandler
    .word    0
    .word    DMA2_Channel6_IRQHandler
    .word    DMA2_Channel7_IRQHandler
    .word    LPUART1_IRQHandler
    .word    QUADSPI_IRQHandler
    .word    I2C3_EV_IRQHandler
    .word    I2C3_ER_IRQHandler
    .word    SAI1_IRQHandler
    .word    0
    .word    SWPMI1_IRQHandler
    .word    TSC_IRQHandler
    .word    0
    .word    0
    .word    RNG_IRQHandler
    .word    FPU_IRQHandler
    .word    CRS_IRQHandler
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
  .weak    NMI_Handler
    .thumb_set NMI_Handler,Default_Handler
  .weak    HardFault_Handler
    .thumb_set HardFault_Handler,Default_Handler
  .weak    MemManage_Handler
    .thumb_set MemManage_Handler,Default_Handler
  .weak    BusFault_Handler
    .thumb_set BusFault_Handler,Default_Handler
    .weak    UsageFault_Handler
    .thumb_set UsageFault_Handler,Default_Handler
    .weak    SVC_Handler
    .thumb_set SVC_Handler,Default_Handler
    .weak    DebugMon_Handler
    .thumb_set DebugMon_Handler,Default_Handler
    .weak    PendSV_Handler
    .thumb_set PendSV_Handler,Default_Handler
    .weak    SysTick_Handler
    .thumb_set SysTick_Handler,Default_Handler
    .weak    WWDG_IRQHandler
    .thumb_set WWDG_IRQHandler,Default_Handler
    .weak    PVD_PVM_IRQHandler
    .thumb_set PVD_PVM_IRQHandler,Default_Handler
    .weak    TAMP_STAMP_IRQHandler
    .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
    .weak    RTC_WKUP_IRQHandler
    .thumb_set RTC_WKUP_IRQHandler,Default_Handler
    .weak    FLASH_IRQHandler
    .thumb_set FLASH_IRQHandler,Default_Handler
    .weak    RCC_IRQHandler
    .thumb_set RCC_IRQHandler,Default_Handler
    .weak    EXTI0_IRQHandler
    .thumb_set EXTI0_IRQHandler,Default_Handler
    .weak    EXTI1_IRQHandler
    .thumb_set EXTI1_IRQHandler,Default_Handler
    .weak    EXTI2_IRQHandler
    .thumb_set EXTI2_IRQHandler,Default_Handler
    .weak    EXTI3_IRQHandler
    .thumb_set EXTI3_IRQHandler,Default_Handler
    .weak    EXTI4_IRQHandler
    .thumb_set EXTI4_IRQHandler,Default_Handler
    .weak    DMA1_Channel1_IRQHandler
    .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
    .weak    DMA1_Channel2_IRQHandler
    .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
    .weak    DMA1_Channel3_IRQHandler
    .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
    .weak    DMA1_Channel4_IRQHandler
    .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
    .weak    DMA1_Channel5_IRQHandler
    .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
    .weak    DMA1_Channel6_IRQHandler
    .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
    .weak    DMA1_Channel7_IRQHandler
    .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
    .weak    ADC1_IRQHandler
    .thumb_set ADC1_IRQHandler,Default_Handler
    .weak    CAN1_TX_IRQHandler
    .thumb_set CAN1_TX_IRQHandler,Default_Handler
    .weak    CAN1_RX0_IRQHandler
    .thumb_set CAN1_RX0_IRQHandler,Default_Handler
    .weak    CAN1_RX1_IRQHandler
    .thumb_set CAN1_RX1_IRQHandler,Default_Handler
    .weak    CAN1_SCE_IRQHandler
    .thumb_set CAN1_SCE_IRQHandler,Default_Handler
    .weak    EXTI9_5_IRQHandler
    .thumb_set EXTI9_5_IRQHandler,Default_Handler
    .weak    TIM1_BRK_TIM15_IRQHandler
    .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
    .weak    TIM1_UP_TIM16_IRQHandler
    .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
    .weak    TIM1_TRG_COM_IRQHandler
    .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
    .weak    TIM1_CC_IRQHandler
    .thumb_set TIM1_CC_IRQHandler,Default_Handler
    .weak    TIM2_IRQHandler
    .thumb_set TIM2_IRQHandler,Default_Handler
    .weak    I2C1_EV_IRQHandler
    .thumb_set I2C1_EV_IRQHandler,Default_Handler
    .weak    I2C1_ER_IRQHandler
    .thumb_set I2C1_ER_IRQHandler,Default_Handler
    .weak    I2C2_EV_IRQHandler
    .thumb_set I2C2_EV_IRQHandler,Default_Handler
    .weak    I2C2_ER_IRQHandler
    .thumb_set I2C2_ER_IRQHandler,Default_Handler
    .weak    SPI1_IRQHandler
    .thumb_set SPI1_IRQHandler,Default_Handler
    .weak    SPI2_IRQHandler
    .thumb_set SPI2_IRQHandler,Default_Handler
    .weak    USART1_IRQHandler
    .thumb_set USART1_IRQHandler,Default_Handler
    .weak    USART2_IRQHandler
    .thumb_set USART2_IRQHandler,Default_Handler
    .weak    USART3_IRQHandler
    .thumb_set USART3_IRQHandler,Default_Handler
    .weak    EXTI15_10_IRQHandler
    .thumb_set EXTI15_10_IRQHandler,Default_Handler
    .weak    RTC_Alarm_IRQHandler
    .thumb_set RTC_Alarm_IRQHandler,Default_Handler
    .weak    SDMMC1_IRQHandler
    .thumb_set SDMMC1_IRQHandler,Default_Handler
    .weak    SPI3_IRQHandler
    .thumb_set SPI3_IRQHandler,Default_Handler
    .weak    TIM6_DAC_IRQHandler
    .thumb_set TIM6_DAC_IRQHandler,Default_Handler
    .weak    TIM7_IRQHandler
    .thumb_set TIM7_IRQHandler,Default_Handler
    .weak    DMA2_Channel1_IRQHandler
    .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
    .weak    DMA2_Channel2_IRQHandler
    .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
    .weak    DMA2_Channel3_IRQHandler
    .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
    .weak    DMA2_Channel4_IRQHandler
    .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
    .weak    DMA2_Channel5_IRQHandler
    .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
    .weak    COMP_IRQHandler
    .thumb_set COMP_IRQHandler,Default_Handler
    .weak    LPTIM1_IRQHandler
    .thumb_set LPTIM1_IRQHandler,Default_Handler
    .weak    LPTIM2_IRQHandler
    .thumb_set LPTIM2_IRQHandler,Default_Handler
    .weak    DMA2_Channel6_IRQHandler
    .thumb_set DMA2_Channel6_IRQHandler,Default_Handler
    .weak    DMA2_Channel7_IRQHandler
    .thumb_set DMA2_Channel7_IRQHandler,Default_Handler
    .weak    LPUART1_IRQHandler
    .thumb_set LPUART1_IRQHandler,Default_Handler
    .weak    QUADSPI_IRQHandler
    .thumb_set QUADSPI_IRQHandler,Default_Handler
    .weak    I2C3_EV_IRQHandler
    .thumb_set I2C3_EV_IRQHandler,Default_Handler
    .weak    I2C3_ER_IRQHandler
    .thumb_set I2C3_ER_IRQHandler,Default_Handler
    .weak    SAI1_IRQHandler
    .thumb_set SAI1_IRQHandler,Default_Handler
    .weak    SWPMI1_IRQHandler
    .thumb_set SWPMI1_IRQHandler,Default_Handler
    .weak    TSC_IRQHandler
    .thumb_set TSC_IRQHandler,Default_Handler
    .weak    RNG_IRQHandler
    .thumb_set RNG_IRQHandler,Default_Handler
    .weak    FPU_IRQHandler
    .thumb_set FPU_IRQHandler,Default_Handler
    .weak    CRS_IRQHandler
    .thumb_set CRS_IRQHandler,Default_Handler
Production/ISKBoard_QCTester/ISKBoard_QCTester Debug.launch
New file
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.st.stm32cube.ide.mcu.debug.launch.launchConfigurationType">
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.access_port_id" value="0"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.cubeprog_external_loaders" value="[]"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.enable_live_expr" value="true"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.enable_swv" value="false"/>
    <intAttribute key="com.st.stm32cube.ide.mcu.debug.launch.formatVersion" value="2"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.ip_address_local" value="localhost"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.enabled" value="false"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.value" value=""/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.loadList" value="{&quot;fItems&quot;:[{&quot;fIsFromMainTab&quot;:true,&quot;fPath&quot;:&quot;Debug/ISKBoard_QCTester.elf&quot;,&quot;fProjectName&quot;:&quot;ISKBoard_QCTester&quot;,&quot;fPerformBuild&quot;:true,&quot;fDownload&quot;:true,&quot;fLoadSymbols&quot;:true}]}"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.override_start_address_mode" value="default"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.remoteCommand" value="target remote"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startServer" value="true"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startuptab.exception.divby0" value="true"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startuptab.exception.unaligned" value="false"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startuptab.haltonexception" value="true"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.swd_mode" value="true"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.swv_port" value="61235"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.swv_trace_hclk" value="80000000"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.useRemoteTarget" value="true"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.vector_table" value=""/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.verify_flash_download" value="true"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.cti_allow_halt" value="false"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.cti_signal_halt" value="false"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.enable_logging" value="false"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.enable_max_halt_delay" value="false"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.enable_shared_stlink" value="false"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.frequency" value="0"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.halt_all_on_reset" value="false"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.log_file" value="E:\STM32CubeIDE\ISKBoard_QCTester\Debug\st-link_gdbserver_log.txt"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.low_power_debug" value="enable"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.max_halt_delay" value="2"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.reset_strategy" value="connect_under_reset"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.stlink_check_serial_number" value="false"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.stlink_txt_serial_number" value=""/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.watchdog_config" value="none"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlinkenable_rtos" value="false"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlinkrestart_configurations" value="{&quot;fVersion&quot;:1,&quot;fItems&quot;:[{&quot;fDisplayName&quot;:&quot;Reset&quot;,&quot;fIsSuppressible&quot;:false,&quot;fResetAttribute&quot;:&quot;Software system reset&quot;,&quot;fResetStrategies&quot;:[{&quot;fDisplayName&quot;:&quot;Software system reset&quot;,&quot;fLaunchAttribute&quot;:&quot;system_reset&quot;,&quot;fGdbCommands&quot;:[&quot;monitor reset\r\n&quot;],&quot;fCmdOptions&quot;:[&quot;-g&quot;]},{&quot;fDisplayName&quot;:&quot;Hardware reset&quot;,&quot;fLaunchAttribute&quot;:&quot;hardware_reset&quot;,&quot;fGdbCommands&quot;:[&quot;monitor reset hardware\r\n&quot;],&quot;fCmdOptions&quot;:[&quot;-g&quot;]},{&quot;fDisplayName&quot;:&quot;Core reset&quot;,&quot;fLaunchAttribute&quot;:&quot;core_reset&quot;,&quot;fGdbCommands&quot;:[&quot;monitor reset core\r\n&quot;],&quot;fCmdOptions&quot;:[&quot;-g&quot;]},{&quot;fDisplayName&quot;:&quot;None&quot;,&quot;fLaunchAttribute&quot;:&quot;no_reset&quot;,&quot;fGdbCommands&quot;:[],&quot;fCmdOptions&quot;:[&quot;-g&quot;]}],&quot;fGdbCommandGroup&quot;:{&quot;name&quot;:&quot;Additional commands&quot;,&quot;commands&quot;:[]},&quot;fStartApplication&quot;:true}]}"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.enableRtosProxy" value="false"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyCustomProperties" value=""/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyDriver" value="threadx"/>
    <booleanAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyDriverAuto" value="false"/>
    <stringAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyDriverPort" value="cortex_m0"/>
    <intAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyPort" value="60000"/>
    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="false"/>
    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="false"/>
    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value=""/>
    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDeviceId" value="com.st.stm32cube.ide.mcu.debug.stlink"/>
    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
    <intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="61234"/>
    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
    <stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
    <booleanAttribute key="org.eclipse.cdt.dsf.gdb.NON_STOP" value="false"/>
    <booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
    <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
    <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
    <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
    <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
    <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
    <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/ISKBoard_QCTester.elf"/>
    <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="ISKBoard_QCTester"/>
    <booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
    <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.88492984"/>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
        <listEntry value="/ISKBoard_QCTester"/>
    </listAttribute>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
        <listEntry value="4"/>
    </listAttribute>
    <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;&gt;&lt;gdbmemoryBlockExpression address=&quot;1342242392&quot; label=&quot;0x5000fe58&quot;/&gt;&lt;/memoryBlockExpressionList&gt;"/>
    <stringAttribute key="process_factory_id" value="com.st.stm32cube.ide.mcu.debug.launch.HardwareDebugProcessFactory"/>
    <stringAttribute key="saved_expressions&lt;seperator&gt;Unknown" value="0x5000fe58,0xfffffff1"/>
</launchConfiguration>
Production/ISKBoard_QCTester/ISKBoard_QCTester.ioc
New file
@@ -0,0 +1,367 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_15
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_16
ADC1.CommonPathInternal=null|null|null|null
ADC1.ContinuousConvMode=ENABLE
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,NbrOfConversion,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,ContinuousConvMode,CommonPathInternal
ADC1.NbrOfConversion=2
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.Rank-1\#ChannelRegularConversion=2
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
ADC1.master=1
CAD.formats=
CAD.pinconfig=
CAD.provider=
CAN1.BS1=CAN_BS1_9TQ
CAN1.BS2=CAN_BS2_6TQ
CAN1.CalculateBaudRate=500000
CAN1.CalculateTimeBit=2000
CAN1.CalculateTimeQuantum=125.0
CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,Prescaler,BS1,BS2
CAN1.Prescaler=10
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
LPUART1.BaudRate=115200
LPUART1.IPParameters=BaudRate,WordLength
LPUART1.WordLength=UART_WORDLENGTH_8B
Mcu.CPN=STM32L431RCT6
Mcu.Family=STM32L4
Mcu.IP0=ADC1
Mcu.IP1=CAN1
Mcu.IP10=USART2
Mcu.IP11=USART3
Mcu.IP2=LPUART1
Mcu.IP3=NVIC
Mcu.IP4=RCC
Mcu.IP5=SPI1
Mcu.IP6=SYS
Mcu.IP7=TIM1
Mcu.IP8=TIM6
Mcu.IP9=USART1
Mcu.IPNb=12
Mcu.Name=STM32L431R(B-C)Tx
Mcu.Package=LQFP64
Mcu.Pin0=PH0-OSC_IN (PH0)
Mcu.Pin1=PH1-OSC_OUT (PH1)
Mcu.Pin10=PA5
Mcu.Pin11=PA6
Mcu.Pin12=PA7
Mcu.Pin13=PC4
Mcu.Pin14=PC5
Mcu.Pin15=PB0
Mcu.Pin16=PB1
Mcu.Pin17=PB2
Mcu.Pin18=PB10
Mcu.Pin19=PB11
Mcu.Pin2=PC0
Mcu.Pin20=PB12
Mcu.Pin21=PB13
Mcu.Pin22=PB14
Mcu.Pin23=PC6
Mcu.Pin24=PC7
Mcu.Pin25=PC8
Mcu.Pin26=PC9
Mcu.Pin27=PA9
Mcu.Pin28=PA10
Mcu.Pin29=PA11
Mcu.Pin3=PC1
Mcu.Pin30=PA13 (JTMS-SWDIO)
Mcu.Pin31=PA14 (JTCK-SWCLK)
Mcu.Pin32=PA15 (JTDI)
Mcu.Pin33=PC10
Mcu.Pin34=PC11
Mcu.Pin35=PC12
Mcu.Pin36=PD2
Mcu.Pin37=PB3 (JTDO-TRACESWO)
Mcu.Pin38=PB4 (NJTRST)
Mcu.Pin39=PB5
Mcu.Pin4=PC2
Mcu.Pin40=PB8
Mcu.Pin41=PB9
Mcu.Pin42=VP_TIM6_VS_ClockSourceINT
Mcu.Pin5=PC3
Mcu.Pin6=PA1
Mcu.Pin7=PA2
Mcu.Pin8=PA3
Mcu.Pin9=PA4
Mcu.PinsNb=43
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32L431RCTx
MxCube.Version=6.8.0
MxDb.Version=DB.6.0.80
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.CAN1_RX0_IRQn=true\:1\:0\:true\:false\:true\:true\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.EXTI15_10_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.LPUART1_IRQn=true\:3\:0\:true\:false\:true\:true\:true\:true
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.USART3_IRQn=true\:2\:0\:true\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA1.GPIOParameters=GPIO_Label
PA1.GPIO_Label=mikrobus_pwm
PA1.Locked=true
PA1.Signal=GPIO_Input
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA11.Signal=S_TIM1_CH4
PA13\ (JTMS-SWDIO).Mode=Serial_Wire
PA13\ (JTMS-SWDIO).Signal=SYS_JTMS-SWDIO
PA14\ (JTCK-SWCLK).Mode=Serial_Wire
PA14\ (JTCK-SWCLK).Signal=SYS_JTCK-SWCLK
PA15\ (JTDI).GPIOParameters=GPIO_Label
PA15\ (JTDI).GPIO_Label=mikrobus_cs
PA15\ (JTDI).Locked=true
PA15\ (JTDI).Signal=GPIO_Output
PA2.Mode=Asynchronous
PA2.Signal=USART2_TX
PA3.Mode=Asynchronous
PA3.Signal=USART2_RX
PA4.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PA4.GPIO_Label=SPI1_CS
PA4.GPIO_Speed=GPIO_SPEED_FREQ_LOW
PA4.Locked=true
PA4.PinState=GPIO_PIN_SET
PA4.Signal=GPIO_Output
PA5.Locked=true
PA5.Mode=Full_Duplex_Master
PA5.Signal=SPI1_SCK
PA6.Mode=Full_Duplex_Master
PA6.Signal=SPI1_MISO
PA7.Mode=Full_Duplex_Master
PA7.Signal=SPI1_MOSI
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB0.Signal=ADCx_IN15
PB1.Signal=ADCx_IN16
PB10.GPIOParameters=GPIO_Label
PB10.GPIO_Label=mikrobus_scl
PB10.Locked=true
PB10.Signal=GPIO_Output
PB11.GPIOParameters=GPIO_Label
PB11.GPIO_Label=mikrobus_sda
PB11.Locked=true
PB11.Signal=GPIO_Output
PB12.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI
PB12.GPIO_Label=Key1
PB12.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PB12.Locked=true
PB12.Signal=GPXTI12
PB13.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI
PB13.GPIO_Label=Key2
PB13.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PB13.Locked=true
PB13.Signal=GPXTI13
PB14.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI
PB14.GPIO_Label=Key3
PB14.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
PB14.Locked=true
PB14.Signal=GPXTI14
PB2.GPIOParameters=PinState,GPIO_Label
PB2.GPIO_Label=LedBlue
PB2.Locked=true
PB2.PinState=GPIO_PIN_SET
PB2.Signal=GPIO_Output
PB3\ (JTDO-TRACESWO).GPIOParameters=PinState,GPIO_Label
PB3\ (JTDO-TRACESWO).GPIO_Label=WiFiRst
PB3\ (JTDO-TRACESWO).Locked=true
PB3\ (JTDO-TRACESWO).PinState=GPIO_PIN_SET
PB3\ (JTDO-TRACESWO).Signal=GPIO_Output
PB4\ (NJTRST).GPIOParameters=GPIO_Label
PB4\ (NJTRST).GPIO_Label=mikrobus_int
PB4\ (NJTRST).Locked=true
PB4\ (NJTRST).Signal=GPIO_Output
PB5.GPIOParameters=GPIO_Label
PB5.GPIO_Label=mikrobus_rst
PB5.Locked=true
PB5.Signal=GPIO_Output
PB8.Mode=CAN_Activate
PB8.Signal=CAN1_RX
PB9.Locked=true
PB9.Mode=CAN_Activate
PB9.Signal=CAN1_TX
PC0.Mode=Asynchronous
PC0.Signal=LPUART1_RX
PC1.Mode=Asynchronous
PC1.Signal=LPUART1_TX
PC10.GPIOParameters=GPIO_Label
PC10.GPIO_Label=mikrobus_sck
PC10.Locked=true
PC10.Signal=GPIO_Output
PC11.GPIOParameters=GPIO_Label
PC11.GPIO_Label=mikrobus_miso
PC11.Locked=true
PC11.Signal=GPIO_Output
PC12.GPIOParameters=GPIO_Label
PC12.GPIO_Label=mikrobus_mosi
PC12.Locked=true
PC12.Signal=GPIO_Output
PC2.GPIOParameters=GPIO_Label
PC2.GPIO_Label=StripLights
PC2.Locked=true
PC2.Signal=GPIO_Output
PC3.GPIOParameters=GPIO_Label
PC3.GPIO_Label=mikrobus_an
PC3.Locked=true
PC3.Signal=GPIO_Output
PC4.Mode=Asynchronous
PC4.Signal=USART3_TX
PC5.Mode=Asynchronous
PC5.Signal=USART3_RX
PC6.GPIOParameters=PinState,GPIO_Label
PC6.GPIO_Label=LedGreen
PC6.Locked=true
PC6.PinState=GPIO_PIN_SET
PC6.Signal=GPIO_Output
PC7.GPIOParameters=GPIO_Label
PC7.GPIO_Label=RS485_Dir
PC7.Locked=true
PC7.Signal=GPIO_Output
PC8.GPIOParameters=GPIO_Label
PC8.GPIO_Label=CAN_STB
PC8.Locked=true
PC8.Signal=GPIO_Output
PC9.GPIOParameters=PinState,GPIO_Label
PC9.GPIO_Label=LedRed
PC9.Locked=true
PC9.PinState=GPIO_PIN_SET
PC9.Signal=GPIO_Output
PD2.GPIOParameters=GPIO_Label
PD2.GPIO_Label=Relay
PD2.Locked=true
PD2.Signal=GPIO_Output
PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator
PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32L431RCTx
ProjectManager.FirmwarePackage=STM32Cube FW_L4 V1.17.2
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=ISKBoard_QCTester.ioc
ProjectManager.ProjectName=ISKBoard_QCTester
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=STM32CubeIDE
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART2_UART_Init-USART2-false-HAL-true,4-MX_USART3_UART_Init-USART3-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_LPUART1_UART_Init-LPUART1-false-HAL-true,7-MX_ADC1_Init-ADC1-false-HAL-true,8-MX_TIM6_Init-TIM6-false-HAL-true,9-MX_TIM1_Init-TIM1-false-HAL-true,10-MX_SPI1_Init-SPI1-false-HAL-true,11-MX_CAN1_Init-CAN1-false-HAL-true
RCC.ADCFreq_Value=12000000
RCC.AHBFreq_Value=80000000
RCC.APB1Freq_Value=80000000
RCC.APB1TimFreq_Value=80000000
RCC.APB2Freq_Value=80000000
RCC.APB2TimFreq_Value=80000000
RCC.CortexFreq_Value=80000000
RCC.FCLKCortexFreq_Value=80000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=80000000
RCC.HSE_VALUE=8000000
RCC.HSI48_VALUE=48000000
RCC.HSI_VALUE=16000000
RCC.I2C1Freq_Value=80000000
RCC.I2C2Freq_Value=80000000
RCC.I2C3Freq_Value=80000000
RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSI_VALUE,MCO1PinFreq_Value,MSI_VALUE,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1R,PLLSAI1RoutputFreq_Value,PLLSourceVirtual,PWRFreq_Value,RNGFreq_Value,SAI1Freq_Value,SDMMCFreq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value
RCC.LPTIM1Freq_Value=80000000
RCC.LPTIM2Freq_Value=80000000
RCC.LPUART1Freq_Value=80000000
RCC.LSCOPinFreq_Value=32000
RCC.LSE_VALUE=32768
RCC.LSI_VALUE=32000
RCC.MCO1PinFreq_Value=80000000
RCC.MSI_VALUE=4000000
RCC.PLLN=20
RCC.PLLPoutputFreq_Value=22857142.85714286
RCC.PLLQoutputFreq_Value=80000000
RCC.PLLRCLKFreq_Value=80000000
RCC.PLLSAI1N=9
RCC.PLLSAI1PoutputFreq_Value=10285714.285714285
RCC.PLLSAI1QoutputFreq_Value=36000000
RCC.PLLSAI1R=RCC_PLLR_DIV6
RCC.PLLSAI1RoutputFreq_Value=12000000
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.PWRFreq_Value=80000000
RCC.RNGFreq_Value=36000000
RCC.SAI1Freq_Value=10285714.285714285
RCC.SDMMCFreq_Value=36000000
RCC.SWPMI1Freq_Value=80000000
RCC.SYSCLKFreq_VALUE=80000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.USART1Freq_Value=80000000
RCC.USART2Freq_Value=80000000
RCC.USART3Freq_Value=80000000
RCC.VCOInputFreq_Value=8000000
RCC.VCOOutputFreq_Value=160000000
RCC.VCOSAI1OutputFreq_Value=72000000
SH.ADCx_IN15.0=ADC1_IN15,IN15-Single-Ended
SH.ADCx_IN15.ConfNb=1
SH.ADCx_IN16.0=ADC1_IN16,IN16-Single-Ended
SH.ADCx_IN16.ConfNb=1
SH.GPXTI12.0=GPIO_EXTI12
SH.GPXTI12.ConfNb=1
SH.GPXTI13.0=GPIO_EXTI13
SH.GPXTI13.ConfNb=1
SH.GPXTI14.0=GPIO_EXTI14
SH.GPXTI14.ConfNb=1
SH.S_TIM1_CH4.0=TIM1_CH4,PWM Generation4 CH4
SH.S_TIM1_CH4.ConfNb=1
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4
SPI1.CLKPhase=SPI_PHASE_2EDGE
SPI1.CLKPolarity=SPI_POLARITY_HIGH
SPI1.CalculateBaudRate=20.0 MBits/s
SPI1.DataSize=SPI_DATASIZE_8BIT
SPI1.Direction=SPI_DIRECTION_2LINES
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity,CLKPhase
SPI1.Mode=SPI_MODE_MASTER
SPI1.VirtualType=VM_MASTER
TIM1.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM1.IPParameters=Channel-PWM Generation4 CH4,Prescaler,Period,Pulse-PWM Generation4 CH4
TIM1.Period=370-1
TIM1.Prescaler=80-1
TIM1.Pulse-PWM\ Generation4\ CH4=185
TIM6.IPParameters=Prescaler,Period
TIM6.Period=1
TIM6.Prescaler=80-1
USART1.IPParameters=VirtualMode-Asynchronous
USART1.VirtualMode-Asynchronous=VM_ASYNC
USART2.IPParameters=VirtualMode-Asynchronous
USART2.VirtualMode-Asynchronous=VM_ASYNC
USART3.IPParameters=VirtualMode-Asynchronous
USART3.VirtualMode-Asynchronous=VM_ASYNC
VP_TIM6_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM6_VS_ClockSourceINT.Signal=TIM6_VS_ClockSourceINT
board=custom
isbadioc=false
Production/ISKBoard_QCTester/STM32L431RCTX_FLASH.ld
New file
@@ -0,0 +1,187 @@
/*
******************************************************************************
**
** @file        : LinkerScript.ld
**
** @author      : Auto-generated by STM32CubeIDE
**
** @brief       : Linker script for STM32L431RCTx Device from STM32L4 series
**                      256Kbytes FLASH
**                      64Kbytes RAM
**                      16Kbytes RAM2
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed as is, without any warranty
**                of any kind.
**
******************************************************************************
** @attention
**
** Copyright (c) 2023 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
******************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 64K
  RAM2    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 16K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 256K
}
/* Sections */
SECTIONS
{
  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH
  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH
  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH
  .ARM.extab   : {
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >FLASH
  .ARM : {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >FLASH
  .preinit_array     :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH
  .init_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH
  .fini_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH
  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);
  /* Initialized data sections into "RAM" Ram type memory */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */
    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH
  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM
  /* User_heap_stack section, used to check that there is enough "RAM" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM
  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }
  .ARM.attributes 0 : { *(.ARM.attributes) }
}