Browse Source

创建

master
sc 5 months ago
commit
da43152a7e
  1. 1241
      828ECO/.config
  2. 230
      828ECO/.cproject
  3. 36
      828ECO/.gitattributes
  4. 37
      828ECO/.gitignore
  5. 27
      828ECO/.project
  6. BIN
      828ECO/.settings/.rtmenus
  7. 63
      828ECO/.settings/828ECO.DAPLink.Debug.rttlaunch
  8. 91
      828ECO/.settings/828ECO.JLink.Debug.rttlaunch
  9. 58
      828ECO/.settings/828ECO.Qemu.Debug.rttlaunch
  10. 57
      828ECO/.settings/828ECO.STLink.Debug.rttlaunch
  11. 2
      828ECO/.settings/ilg.gnumcueclipse.managedbuild.cross.arm.prefs
  12. 14
      828ECO/.settings/language.settings.xml
  13. 2
      828ECO/.settings/org.eclipse.core.resources.prefs
  14. 3
      828ECO/.settings/org.eclipse.core.runtime.prefs
  15. 22
      828ECO/.settings/projcfg.ini
  16. 32
      828ECO/Kconfig
  17. 15
      828ECO/SConscript
  18. 36
      828ECO/SConstruct
  19. 28
      828ECO/applications/main.c
  20. 39
      828ECO/drivers/board.c
  21. 543
      828ECO/drivers/board.h
  22. 286
      828ECO/drivers/drv_adc.c
  23. 788
      828ECO/drivers/drv_can.c
  24. 107
      828ECO/drivers/drv_common.c
  25. 218
      828ECO/drivers/drv_dac.c
  26. 1192
      828ECO/drivers/drv_enet.c
  27. 945
      828ECO/drivers/drv_gpio.c
  28. 278
      828ECO/drivers/drv_hwtimer.c
  29. 622
      828ECO/drivers/drv_i2c.c
  30. 403
      828ECO/drivers/drv_lcd.c
  31. 296
      828ECO/drivers/drv_pwm.c
  32. 443
      828ECO/drivers/drv_rtc.c
  33. 3278
      828ECO/drivers/drv_sdio.c
  34. 640
      828ECO/drivers/drv_spi.c
  35. 1165
      828ECO/drivers/drv_usart.c
  36. 149
      828ECO/drivers/drv_wdt.c
  37. 438
      828ECO/drivers/include/config/adc_config.h
  38. 83
      828ECO/drivers/include/config/can_config.h
  39. 51
      828ECO/drivers/include/config/dac_config.h
  40. 59
      828ECO/drivers/include/config/enet_config.h
  41. 195
      828ECO/drivers/include/config/hwtimer_config.h
  42. 146
      828ECO/drivers/include/config/i2c_config.h
  43. 145
      828ECO/drivers/include/config/pwm_config.h
  44. 178
      828ECO/drivers/include/config/spi_config.h
  45. 204
      828ECO/drivers/include/config/uart_config.h
  46. 40
      828ECO/drivers/include/drv_adc.h
  47. 109
      828ECO/drivers/include/drv_can.h
  48. 40
      828ECO/drivers/include/drv_common.h
  49. 21
      828ECO/drivers/include/drv_config.h
  50. 41
      828ECO/drivers/include/drv_dac.h
  51. 58
      828ECO/drivers/include/drv_dma.h
  52. 98
      828ECO/drivers/include/drv_enet.h
  53. 93
      828ECO/drivers/include/drv_gpio.h
  54. 72
      828ECO/drivers/include/drv_hwtimer.h
  55. 43
      828ECO/drivers/include/drv_i2c.h
  56. 66
      828ECO/drivers/include/drv_lcd.h
  57. 32
      828ECO/drivers/include/drv_legacy.h
  58. 28
      828ECO/drivers/include/drv_log.h
  59. 45
      828ECO/drivers/include/drv_pwm.h
  60. 297
      828ECO/drivers/include/drv_sdio.h
  61. 81
      828ECO/drivers/include/drv_spi.h
  62. 82
      828ECO/drivers/include/drv_usart.h
  63. 1285
      828ECO/drivers/include/synopsys_emac.h
  64. 29
      828ECO/drivers/include/usb/drv_otghs_dev.h
  65. 34
      828ECO/drivers/include/usb/drv_otghs_host.h
  66. 369
      828ECO/drivers/include/usb/drv_usb_core.h
  67. 195
      828ECO/drivers/include/usb/drv_usb_dev.h
  68. 93
      828ECO/drivers/include/usb/drv_usb_host.h
  69. 42
      828ECO/drivers/include/usb/drv_usb_hw.h
  70. 728
      828ECO/drivers/include/usb/drv_usb_regs.h
  71. 28
      828ECO/drivers/include/usb/drv_usbd_int.h
  72. 19
      828ECO/drivers/include/usb/drv_usbh_int.h
  73. 48
      828ECO/drivers/include/usb/drv_usbh_pipe.h
  74. 41
      828ECO/drivers/include/usb/drv_usbh_transc.h
  75. 139
      828ECO/drivers/include/usb/usb_conf.h
  76. 285
      828ECO/drivers/synopsys_emac.c
  77. 336
      828ECO/drivers/usb/drv_otghs_dev.c
  78. 315
      828ECO/drivers/usb/drv_otghs_host.c
  79. 440
      828ECO/drivers/usb/drv_usb_core.c
  80. 755
      828ECO/drivers/usb/drv_usb_dev.c
  81. 448
      828ECO/drivers/usb/drv_usb_host.c
  82. 703
      828ECO/drivers/usb/drv_usbd_int.c
  83. 693
      828ECO/drivers/usb/drv_usbh_int.c
  84. 178
      828ECO/drivers/usb/drv_usbh_pipe.c
  85. 147
      828ECO/drivers/usb/drv_usbh_trans.c
  86. 733
      828ECO/drivers/usb/gd32h7_usb_hw.c
  87. 405
      828ECO/libraries/CMSIS/GD/GD32H75E/Include/gd32h75e.h
  88. 111
      828ECO/libraries/CMSIS/GD/GD32H75E/Include/gd32h75e_err_report.h
  89. 76
      828ECO/libraries/CMSIS/GD/GD32H75E/Include/gd32h75e_libopt.h
  90. 56
      828ECO/libraries/CMSIS/GD/GD32H75E/Include/system_gd32h75e.h
  91. 750
      828ECO/libraries/CMSIS/GD/GD32H75E/Source/GCC/startup_gd32h75e.s
  92. 61
      828ECO/libraries/CMSIS/GD/GD32H75E/Source/gd32h75e_err_report.c
  93. 877
      828ECO/libraries/CMSIS/GD/GD32H75E/Source/system_gd32h75e.c
  94. 446
      828ECO/libraries/CMSIS/cachel1_armv7.h
  95. 304
      828ECO/libraries/CMSIS/cmsis_compiler.h
  96. 2226
      828ECO/libraries/CMSIS/cmsis_gcc.h
  97. 40
      828ECO/libraries/CMSIS/cmsis_version.h
  98. 2408
      828ECO/libraries/CMSIS/core_cm7.h
  99. 277
      828ECO/libraries/CMSIS/mpu_armv7.h
  100. 799
      828ECO/libraries/GD32H75E_standard_peripheral/Include/gd32h75e_adc.h

1241
828ECO/.config

File diff suppressed because it is too large

230
828ECO/.cproject

@ -0,0 +1,230 @@
<?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="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" 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 artifactName="rtthread" 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="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" name="Debug" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug">
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094." name="/" resourcePath="">
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.1201710416" name="ARM Cross GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.251260409" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting.1365878149" name="Create extended listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting" useByScannerDiscovery="false" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.709136944" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1986446770" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.none" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1312975261" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" useByScannerDiscovery="true" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1538128212" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" useByScannerDiscovery="true" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.2136804218" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.244767666" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.1055848773" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.default" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.501941135" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.dwarf2" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.1696308067" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" useByScannerDiscovery="false" value="GNU Tools for ARM Embedded Processors" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1558403188" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.749415257" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m7" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.2114153533" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1600865811" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1109963929" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.1040883831" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1678200391" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.1171840296" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.342604837" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.898269225" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" useByScannerDiscovery="false" value="size" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.2016398076" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" useByScannerDiscovery="false" value="make" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.1606171496" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.540792084" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" useByScannerDiscovery="false" value="1287942917" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture.430121817" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.arch.none" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.966735324" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.hard" valueType="enumerated" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1381561249" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" useByScannerDiscovery="true" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.target.other.2041717463" name="Other target flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.target.other" useByScannerDiscovery="true" value="" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.1463655269" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.fpv5spd16" valueType="enumerated" />
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1798638225" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform" />
<builder buildPath="${workspace_loc:/qemu-vexpress-a9}/Debug" cleanBuildTarget="clean2" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1736709688" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder" />
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1810966071" name="GNU ARM Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1072524326" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.161242639" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;" />
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.1521934876" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" useByScannerDiscovery="true" />
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.flags.1325367962" name="Assembler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.flags" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="-mimplicit-it=thumb" />
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.1843333483" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input" />
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1570350559" name="GNU ARM Cross C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.634882052" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers//include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers//include//config}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers//include//usb}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/libraries//CMSIS}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/libraries//CMSIS//GD//GD32H75E//Include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/libraries//GD32H75E_standard_peripheral//Include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/.}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/applications}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//.}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/phy}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/smp_call}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/finsh}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/epoll}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/eventfd}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/poll}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/ipc}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/net/utest}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/libcpu/arm/common}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/libcpu/arm/cortex-m7}&quot;" />
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.100549972" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="SOC_FAMILY_GD32" />
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H7" />
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H75E" />
<listOptionValue builtIn="false" value="GD32H75E" />
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other.2133065240" name="Other compiler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other" useByScannerDiscovery="true" value="" valueType="string" />
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.files.714348818" name="Include files (-include)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.files" useByScannerDiscovery="true" valueType="includeFiles">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/rtconfig_preinc.h}&quot;" />
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.992053063" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input" />
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.869072473" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.1167322178" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart.351692886" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostdlibs.1009243715" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs.2016026082" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.923990336" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option defaultValue="true" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.shared.548869459" name="Shared (-shared)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.shared" useByScannerDiscovery="false" valueType="boolean" />
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.1818777301" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//linkscripts//GD32H75EYM//link.ld}&quot;" />
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.1135656995" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" useByScannerDiscovery="false">
<listOptionValue builtIn="false" value="c " />
<listOptionValue builtIn="false" value="m " />
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.paths.36884122" name="Library search path (-L)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.paths" useByScannerDiscovery="false" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.396049466" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" useByScannerDiscovery="false" value="" valueType="string" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref.1645737861" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean" />
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.334732222" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)" />
<additionalInput kind="additionalinput" paths="$(LIBS)" />
</inputType>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.1601059928" name="GNU ARM Cross C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.437759352" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean" />
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile.1101974459" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//linkscripts//GD32H75EYM//link.ld}&quot;" />
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref.2007675975" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.2105838438" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs.934137837" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs" useByScannerDiscovery="false" valueType="libs" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart.2118356996" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs.1427884346" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs.1433863653" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections.1387745410" name="Print removed sections (-Xlinker --print-gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip.1230158061" name="Omit all symbol information (-s)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap.1307581821" name="Print link map (-Xlinker --print-map)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat.960778920" name="Use float with nano printf (-u _printf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usescanffloat.637205035" name="Use float with nano scanf (-u _scanf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usescanffloat" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys.1948314201" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.verbose.273162112" name="Verbose (-v)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.verbose" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.paths.1399535143" name="Library search path (-L)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.paths" useByScannerDiscovery="false" valueType="libPaths" />
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input.262373798" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)" />
<additionalInput kind="additionalinput" paths="$(LIBS)" />
</inputType>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.506412204" name="GNU ARM Cross Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver" />
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.1461589245" name="GNU ARM Cross Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.1937707052" name="Output file format (-O)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.binary" valueType="enumerated" />
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.82359725" name="GNU ARM Cross Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.601724476" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.692505279" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.97345172" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.1342893377" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.1533725981" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean" />
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.1073550295" name="GNU ARM Cross Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.946451386" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format" useByScannerDiscovery="false" />
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.1302177015" name="GNU ARM Cross C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs.704468062" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="SOC_FAMILY_GD32" />
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H7" />
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H75E" />
<listOptionValue builtIn="false" value="GD32H75E" />
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths.302877723" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers//include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers//include//config}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/drivers//include//usb}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/libraries//CMSIS}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/libraries//CMSIS//GD//GD32H75E//Include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/libraries//GD32H75E_standard_peripheral//Include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/.}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}/applications}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//.}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/phy}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/smp_call}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/finsh}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/epoll}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/eventfd}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/poll}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/posix/ipc}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/net/utest}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/libcpu/arm/common}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/libcpu/arm/cortex-m7}&quot;" />
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.files.343249373" name="Include files (-include)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.files" useByScannerDiscovery="true" valueType="includeFiles">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/rtconfig_preinc.h}&quot;" />
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.45918001" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input" />
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="//rt-thread/components/dfs|//rt-thread/components/drivers/ata|//rt-thread/components/drivers/audio|//rt-thread/components/drivers/block|//rt-thread/components/drivers/can|//rt-thread/components/drivers/clk|//rt-thread/components/drivers/core/bus.c|//rt-thread/components/drivers/core/dm.c|//rt-thread/components/drivers/core/driver.c|//rt-thread/components/drivers/core/mnt.c|//rt-thread/components/drivers/core/numa.c|//rt-thread/components/drivers/core/platform.c|//rt-thread/components/drivers/core/platform_ofw.c|//rt-thread/components/drivers/core/power_domain.c|//rt-thread/components/drivers/core/utest|//rt-thread/components/drivers/cputime|//rt-thread/components/drivers/dma|//rt-thread/components/drivers/hwcrypto|//rt-thread/components/drivers/hwtimer|//rt-thread/components/drivers/i2c|//rt-thread/components/drivers/iio|//rt-thread/components/drivers/ipc/completion_mp.c|//rt-thread/components/drivers/ipc/utest|//rt-thread/components/drivers/ktime|//rt-thread/components/drivers/led|//rt-thread/components/drivers/mailbox|//rt-thread/components/drivers/mfd|//rt-thread/components/drivers/misc|//rt-thread/components/drivers/mtd|//rt-thread/components/drivers/nvme|//rt-thread/components/drivers/ofw|//rt-thread/components/drivers/pci|//rt-thread/components/drivers/phy|//rt-thread/components/drivers/phye|//rt-thread/components/drivers/pic|//rt-thread/components/drivers/pin/dev_pin_dm.c|//rt-thread/components/drivers/pin/dev_pin_ofw.c|//rt-thread/components/drivers/pinctrl|//rt-thread/components/drivers/pm|//rt-thread/components/drivers/regulator|//rt-thread/components/drivers/reset|//rt-thread/components/drivers/rtc|//rt-thread/components/drivers/scsi|//rt-thread/components/drivers/sdio|//rt-thread/components/drivers/sensor|//rt-thread/components/drivers/serial/bypass.c|//rt-thread/components/drivers/serial/dev_serial_v2.c|//rt-thread/components/drivers/serial/serial_dm.c|//rt-thread/components/drivers/serial/serial_tty.c|//rt-thread/components/drivers/serial/utest|//rt-thread/components/drivers/smp_call|//rt-thread/components/drivers/spi|//rt-thread/components/drivers/thermal|//rt-thread/components/drivers/touch|//rt-thread/components/drivers/usb|//rt-thread/components/drivers/virtio|//rt-thread/components/drivers/watchdog|//rt-thread/components/drivers/wlan|//rt-thread/components/fal|//rt-thread/components/finsh/msh_file.c|//rt-thread/components/legacy|//rt-thread/components/libc/compilers/armlibc|//rt-thread/components/libc/compilers/dlib|//rt-thread/components/libc/compilers/musl|//rt-thread/components/libc/compilers/picolibc|//rt-thread/components/libc/cplusplus|//rt-thread/components/libc/posix|//rt-thread/components/lwp|//rt-thread/components/mm|//rt-thread/components/mprotect|//rt-thread/components/net|//rt-thread/components/utilities|//rt-thread/components/vbus|//rt-thread/examples|//rt-thread/libcpu/aarch64|//rt-thread/libcpu/arc|//rt-thread/libcpu/arm/AT91SAM7S|//rt-thread/libcpu/arm/AT91SAM7X|//rt-thread/libcpu/arm/am335x|//rt-thread/libcpu/arm/arm926|//rt-thread/libcpu/arm/armv6|//rt-thread/libcpu/arm/common/divsi3.S|//rt-thread/libcpu/arm/cortex-a|//rt-thread/libcpu/arm/cortex-m0|//rt-thread/libcpu/arm/cortex-m23|//rt-thread/libcpu/arm/cortex-m3|//rt-thread/libcpu/arm/cortex-m33|//rt-thread/libcpu/arm/cortex-m4|//rt-thread/libcpu/arm/cortex-m7/context_iar.S|//rt-thread/libcpu/arm/cortex-m7/context_rvds.S|//rt-thread/libcpu/arm/cortex-m7/mpu.c|//rt-thread/libcpu/arm/cortex-m85|//rt-thread/libcpu/arm/cortex-r4|//rt-thread/libcpu/arm/cortex-r52|//rt-thread/libcpu/arm/dm36x|//rt-thread/libcpu/arm/lpc214x|//rt-thread/libcpu/arm/lpc24xx|//rt-thread/libcpu/arm/realview-a8-vmm|//rt-thread/libcpu/arm/s3c24x0|//rt-thread/libcpu/arm/s3c44b0|//rt-thread/libcpu/arm/sep4020|//rt-thread/libcpu/arm/zynqmp-r5|//rt-thread/libcpu/avr32|//rt-thread/libcpu/blackfin|//rt-thread/libcpu/c-sky|//rt-thread/libcpu/ia32|//rt-thread/libcpu/m16c|//rt-thread/libcpu/mips|//rt-thread/libcpu/nios|//rt-thread/libcpu/ppc|//rt-thread/libcpu/risc-v|//rt-thread/libcpu/rx|//rt-thread/libcpu/sim|//rt-thread/libcpu/sparc-v8|//rt-thread/libcpu/ti-dsp|//rt-thread/libcpu/unicore32|//rt-thread/libcpu/v850|//rt-thread/libcpu/xilinx|//rt-thread/src/cpu_mp.c|//rt-thread/src/klibc/rt_vsnprintf_std.c|//rt-thread/src/klibc/utest|//rt-thread/src/memheap.c|//rt-thread/src/scheduler_mp.c|//rt-thread/src/signal.c|//rt-thread/src/slab.c|//rt-thread/src/utest|//rt-thread/tools" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="" />
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings" />
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="qemu-vexpress-a9.ilg.gnuarmeclipse.managedbuild.cross.target.elf.860020518" name="Executable" projectType="ilg.gnuarmeclipse.managedbuild.cross.target.elf" />
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="" />
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094;ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1570350559;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.992053063">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="" />
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders" />
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/project" />
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets" />
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen">
<path value="" />
</doc-comment-owner>
</storageModule>
</cproject>

36
828ECO/.gitattributes

@ -0,0 +1,36 @@
# Sources
*.c text diff=c
*.cc text diff=cpp
*.cxx text diff=cpp
*.cpp text diff=cpp
*.c++ text diff=cpp
*.hpp text diff=cpp
*.h text diff=c
*.h++ text diff=cpp
*.hh text diff=cpp
# Compiled Object files
*.slo binary
*.lo binary
*.o binary
*.obj binary
# Precompiled Headers
*.gch binary
*.pch binary
# Compiled Dynamic libraries
*.so binary
*.dylib binary
*.dll binary
# Compiled Static libraries
*.lai binary
*.la binary
*.a binary
*.lib binary
# Executables
*.exe binary
*.out binary
*.app binary

37
828ECO/.gitignore

@ -0,0 +1,37 @@
*.pyc
*.map
*.dblite
*.elf
*.bin
*.hex
*.axf
*.pdb
*.idb
*.ilk
*.old
build
Debug
*~
*.o
*.obj
*.out
*.bak
*.dep
*.lib
*.i
*.d
.DS_Stor*
.config 3
.config 4
.config 5
*.uimg
GPATH
GRTAGS
GTAGS
.vscode
JLinkLog.txt
JLinkSettings.ini
DebugConfig/
RTE/
settings/
*.uvguix*

27
828ECO/.project

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>828ECO</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>org.eclipse.cdt.core.cnature</nature>
<nature>org.rt-thread.studio.rttnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

BIN
828ECO/.settings/.rtmenus

Binary file not shown.

63
828ECO/.settings/828ECO.DAPLink.Debug.rttlaunch

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.pyocd.launchConfigurationType">
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.adapterName" value="DAP-LINK"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.binFlashStartAddress" value=""/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doContinue" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doDebugInRam" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doFirstReset" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doGdbServerAllocateConsole" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doSecondReset" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doStartGdbServer" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.enableSemihosting" value="true"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.firstResetType" value="init"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbClientOtherOptions" value=""/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerBusSpeed" value="1000000"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerConnectionAddress" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerDeviceName" value="GD32H75EYMJ7"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerEnableSemihosting" value="false"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerExecutable" value="${debugger_install_path}/${daplink_debugger_relative_path}\pyocd.exe"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerFlashMode" value="0"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerGdbPortNumber" value="3333"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerOther" value=""/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerTelnetPortNumber" value="4444"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.otherInitCommands" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.otherRunCommands" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.programMode" value="BIN"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.secondResetType" value="halt"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU PyOCD"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
<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.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="false"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${rtt_gnu_gcc}/arm-none-eabi-gdb.exe"/>
<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="0"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/828ECO"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/>
</launchConfiguration>

91
828ECO/.settings/828ECO.JLink.Debug.rttlaunch

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.jlink.launchConfigurationType">
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.adapterName" value="J-Link"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.binFileStartAddress" value=""/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doConnectToRunning" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doContinue" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doDebugInRam" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doFirstReset" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerAllocateConsole" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerAllocateSemihostingConsole" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerInitRegs" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerLocalOnly" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerSilent" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerVerifyDownload" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doSecondReset" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doStartGdbServer" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableFlashBreakpoints" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSemihosting" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSemihostingIoclientGdbClient" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSemihostingIoclientTelnet" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSwo" value="true"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.eraseEndAddress" value=""/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.eraseMode" value="0"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.eraseStartAddress" value=""/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.firstResetSpeed" value="1000"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.firstResetType" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.flashDeviceName" value="GD32H75EYMJ7"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.flashDownloadHex" value="false"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbClientOtherOptions" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerConnection" value="usb"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerConnectionAddress" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDebugInterface" value="swd"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDeviceEndianness" value="little"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDeviceName" value="GD32H75EYMJ7"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDeviceSpeed" value="1000"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerExecutable" value="${debugger_install_path}/${jlink_debugger_relative_path}\JLinkGDBServerCL.exe"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerGdbPortNumber" value="2331"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerLog" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerOther" value="-singlerun"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerRunAfterStopDebug" value="true"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerSwoPortNumber" value="2332"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerTelnetPortNumber" value="2333"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.interfaceSpeed" value="auto"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.jlinkExecutable" value="${debugger_install_path}/${jlink_debugger_relative_path}\JLink.exe"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.otherInitCommands" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.otherRunCommands" value=""/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.runAfterDownload" value="true"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.secondResetType" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.serailBaudRate" value="115200"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.serailPort" value=""/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.swoEnableTargetCpuFreq" value="0"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.swoEnableTargetPortMask" value="0x1"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.swoEnableTargetSwoFreq" value="0"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}\repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU J-Link"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="2331"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
<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.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${rtt_gnu_gcc}/arm-none-eabi-gdb.exe"/>
<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="0"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/828ECO"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/>
</launchConfiguration>

58
828ECO/.settings/828ECO.Qemu.Debug.rttlaunch

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.qemu.launchConfigurationType">
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doContinue" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doDebugInRam" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doFirstReset" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doSecondReset" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doStartGdbServer" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.enableSemihosting" value="true"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbClientOtherCommands" value="set mem inaccessible-by-default off&#10;"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbClientOtherOptions" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerBoardModel" value="?"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerCpuQuantity" value="1"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerEnableNetwork" value="false"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerExecutable" value="${debugger_install_path}/${qemu_debugger_relative_path}\qemu-system-arm.exe"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerExtraQemuCmd" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerSdcardMemory" value="64.0"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerSerialPort" value="COM1"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerStartup" value="${studio_install_path}/repo/Extract/Debugger_Support_Packages/RealThread/QEMU/4.2.0.4/qemu-system-arm.exe -M ? -sd sd.bin -nographic -S -s"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerTapName" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.otherInitCommands" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.otherRunCommands" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}\repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU QEMU"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="1234"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
<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.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cross_prefix}gdb${cross_suffix}"/>
<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="0"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/828ECO"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/>
</launchConfiguration>

57
828ECO/.settings/828ECO.STLink.Debug.rttlaunch

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.rtthread.studio.debug.gdbjtag.stlink.launchConfigurationType">
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}\repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.connectMode" value="NORMAL"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.debugInterface" value="SWD"/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="3"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.flashVerify" value="false"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<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="org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.genericDevice"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.otherDownloadOption" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.otherGdbserverOption" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="61235"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.resetMode" value=" -hardRst"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.resetRun" value="true"/>
<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.setStopAt" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${rtt_gnu_gcc}/arm-none-eabi-gdb.exe"/>
<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="0"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/828ECO"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/>
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.adapterName" value="ST-LINK"/>
<booleanAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.doContinue" value="true"/>
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.gdbServerDeviceName" value="GD32H75EYMJ7"/>
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.gdbServerExecutable" value="${debugger_install_path}/${stlink_debugger_relative_path}/ST-LINK_gdbserver.exe"/>
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.stlinkGdbServer" value="${debugger_install_path}/${stlink_debugger_relative_path}/tools/bin/STM32_Programmer_CLI.exe"/>
<booleanAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.useRemoteTarget" value="true"/>
</launchConfiguration>

2
828ECO/.settings/ilg.gnumcueclipse.managedbuild.cross.arm.prefs

@ -0,0 +1,2 @@
eclipse.preferences.version=1
toolchain.path.1287942917=${toolchain_install_path}/ARM/GNU_Tools_for_ARM_Embedded_Processors/13.3/bin

14
828ECO/.settings/language.settings.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" 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="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1180059202540270600" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_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>

2
828ECO/.settings/org.eclipse.core.resources.prefs

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

3
828ECO/.settings/org.eclipse.core.runtime.prefs

@ -0,0 +1,3 @@
content-types/enabled=true
content-types/org.eclipse.cdt.core.asmSource/file-extensions=s
eclipse.preferences.version=1

22
828ECO/.settings/projcfg.ini

@ -0,0 +1,22 @@
#RT-Thread Studio Project Configuration
#Wed Feb 11 14:08:06 CST 2026
project_type=rtt
chip_name=GD32H75EYMJ7
cpu_name=None
target_freq=180
clock_source=hsi
dvendor_name=GigaDevice
rx_pin_name=PA10
rtt_path=repo/Extract/RT-Thread_Source_Code/RT-Thread/5.2.2
source_freq=0
csp_path=repo/Extract/Chip_Support_Packages/RealThread/GD32H7xx/2.0.0
sub_series_name=GD32H75E
selected_rtt_version=5.2.2
cfg_version=v3.0
tool_chain=gcc
uart_name=uart1
tx_pin_name=PA9
rtt_nano_path=
output_project_path=C\:/RT-ThreadStudio/workspace
hardware_adapter=J-Link
project_name=828ECO

32
828ECO/Kconfig

@ -0,0 +1,32 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config PLATFORM_DIR
string
option env="PLATFORM_DIR"
default "C:/RT-ThreadStudio/workspace/828ECO/platform"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$PKGS_DIR/packages/misc/samples/Kconfig"
config RT_STUDIO_BUILT_IN
bool
select ARCH_ARM_CORTEX_M7
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y

15
828ECO/SConscript

@ -0,0 +1,15 @@
# for module compiling
import os
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

36
828ECO/SConstruct

@ -0,0 +1,36 @@
import os
import sys
import rtconfig
RTT_ROOT = os.path.normpath(os.getcwd() + '/rt-thread')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
from building import *
except Exception as e:
print("Error message:", e.message)
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
print(RTT_ROOT)
sys.exit(-1)
TARGET = 'rt-thread.elf'
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env.AppendUnique(CPPDEFINES = [])
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
# make a building
DoBuilding(TARGET, objs)

28
828ECO/applications/main.c

@ -0,0 +1,28 @@
/*
* Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2026-02-11 RT-Thread first version
*/
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
int main(void)
{
int count = 1;
LOG_D("Hello RT-Thread!");
while (count++)
{
rt_thread_mdelay(1000);
}
return RT_EOK;
}

39
828ECO/drivers/board.c

@ -0,0 +1,39 @@
/*
* Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2026-02-11 RealThread first version
*/
#include <rtthread.h>
#include <board.h>
#include <drv_common.h>
#ifndef RT_WEAK
#define RT_WEAK rt_weak
#endif
RT_WEAK void rt_hw_board_init()
{
/* Heap initialization */
#if defined(RT_USING_HEAP)
rt_system_heap_init((void *) HEAP_BEGIN, (void *) HEAP_END);
#endif
extern void hw_board_init();
hw_board_init();
/* Set the shell console output device */
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE)
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}

543
828ECO/drivers/board.h

@ -0,0 +1,543 @@
/*
* Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2026-02-11 RealThread first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#ifdef SOC_SERIES_GD32H75E
#include <gd32h75e.h>
#include "gd32h75e_exti.h"
#else
#include <gd32h7xx.h>
#include "gd32h7xx_exti.h"
#endif
#include <drv_gpio.h>
#include "drv_legacy.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*-------------------------- CHIP CONFIG BEGIN --------------------------*/
#define CHIP_FAMILY_GD32
#define CHIP_SERIES_GD32H7
#define CHIP_NAME_GD32H75EYMJ7
/*-------------------------- CHIP CONFIG END --------------------------*/
/*-------------------------- ROM/RAM CONFIG BEGIN --------------------------*/
#define ROM_START ((uint32_t)0x8000000)
#define ROM_SIZE (3840 * 1024)
#define ROM_END ((uint32_t)(ROM_START + ROM_SIZE))
#define RAM_START (0x24000000)
#define RAM_SIZE (512 * 1024)
#define RAM_END (RAM_START + RAM_SIZE)
/*-------------------------- ROM/RAM CONFIG END --------------------------*/
/*-------------------------- UART CONFIG BEGIN --------------------------*/
/** After configuring corresponding UART or UART DMA, you can use it.
*
* STEP 1, define macro define related to the serial port opening based on the serial port number
* such as #define BSP_USING_UART1
*
* STEP 2, according to the corresponding pin of serial port, define the related serial port information macro
* such as #define BSP_UART1_TX_PIN "PA9"
* #define BSP_UART1_RX_PIN "PA10"
*
* STEP 3, if you want using SERIAL DMA, you must open it in the RT-Thread Settings.
* RT-Thread Setting -> Components -> Device Drivers -> Serial Device Drivers -> Enable Serial DMA Mode
*
* STEP 4, according to serial port number to define serial port tx/rx DMA function in the board.h file
* such as #define BSP_UART1_RX_USING_DMA
*
*/
#define BSP_USING_UART1
#define BSP_UART1_TX_PIN "PA9"
#define BSP_UART1_RX_PIN "PA10"
/*-------------------------- UART CONFIG END --------------------------*/
/*-------------------------- I2C CONFIG BEGIN --------------------------*/
/** How to enable and configure I2C (hardware)
*
* STEP 1, enable the I2C driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using I2C device drivers
*
* STEP 2, turn on the I2C instance by defining the related macro, and prefer the
* default board-level settings provided in i2c_config.h.
* e.g. #define BSP_USING_I2C1
*
* STEP 3, if you accept the default pins in i2c_config.h, you are done. No further
* pin configuration is required here.
*
* STEP 4, to override pins, set the port pins below for your MCU package according
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_I2C1_SCL_PIN "PH4"
* #define BSP_I2C1_SDA_PIN "PB11"
*
* STEP 5, to override alternate function (AF), set the AF macro below in this file
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_I2C1_AFIO "AF4"
*
* Notes:
* - For details on using the I2C device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/i2c/i2c
* - If using the default configuration in i2c_config.h, just add the device macro (e.g., BSP_USING_I2C1) in board.h.
* - To use custom pins, follow the definitions below.
*/
/*----------------------- Driver configuration example ----------------------*/
/* #define BSP_USING_I2C1 */
/* #define BSP_I2C1_SCL_PIN "PH4" */
/* #define BSP_I2C1_SDA_PIN "PB11" */
/* #define BSP_I2C1_AFIO "AF4" */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- I2C CONFIG END --------------------------*/
/*-------------------------- SPI CONFIG BEGIN --------------------------*/
/** How to enable and configure SPI (hardware)
*
* STEP 1, enable the SPI driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using SPI Bus/Device drivers
*
* STEP 2, turn on the SPI instance by defining the related macro, and prefer the
* default board-level settings provided in spi_config.h.
* e.g. #define BSP_USING_SPI1
*
* STEP 3, if you accept the default pins in spi_config.h, you are done. No further
* pin configuration is required here.
*
* STEP 4, to override pins, set the port pins below for your MCU package according
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_SPI1_SCK_PIN "PB13"
* #define BSP_SPI1_MISO_PIN "PB14"
* #define BSP_SPI1_MOSI_PIN "PB15"
*
* STEP 5, to override alternate function (AF), set the AF macro below in this file
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_SPI1_AFIO "AF5"
*
* Notes:
* - For details on using the SPI device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi
* - If using the default configuration in spi_config.h, just add the device macro (e.g., BSP_USING_SPI1) in board.h.
* - To use custom pins, follow the definitions below.
*/
/*----------------------- Driver configuration example ----------------------*/
/* #define BSP_USING_SPI1 */
/* #define BSP_SPI1_SCK_PIN "PB13" */
/* #define BSP_SPI1_MISO_PIN "PB14" */
/* #define BSP_SPI1_MOSI_PIN "PB15" */
/* #define BSP_SPI1_AFIO "AF5" */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- SPI CONFIG END --------------------------*/
/*-------------------------- PWM CONFIG BEGIN --------------------------*/
/** How to enable and configure PWM (hardware)
*
* STEP 1, enable the PWM driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using PWM device drivers
*
* STEP 2, turn on the PWM instance by defining the related macro, and prefer the
* default board-level settings provided in pwm_config.h.
* e.g. #define BSP_USING_PWM0
*
* STEP 3, if you accept the default pins in pwm_config.h, you are done. No further
* pin configuration is required here.
*
* STEP 4, to override pins, set the port pins below for your MCU package according
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_PWM0_PIN "PC7"
* #define BSP_PWM0_CHANNEL 3
*
* STEP 5, to override alternate function (AF), set the AF macro below in this file
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_PWM0_AFIO "AF1"
*
* Notes:
* - For details on using the PWM device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/pwm/pwm
* - If using the default configuration in pwm_config.h, just add the device macro (e.g., BSP_USING_PWM0) in board.h.
* - To use custom pins, follow the definitions below.
*/
/*----------------------- PWM Driver configuration example ----------------------*/
/* #define BSP_USING_PWM0 */
/* #define BSP_PWM0_PIN "PC7" */
/* #define BSP_PWM0_CHANNEL 3 */
/* #define BSP_PWM0_AFIO "AF1" */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- PWM CONFIG END --------------------------*/
/*-------------------------- ADC CONFIG BEGIN --------------------------*/
/** How to enable and configure ADC
*
* STEP 1, enable the ADC driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using ADC device drivers
*
* STEP 2, turn on the ADC instance by defining the related macro.
* e.g. #define BSP_USING_ADC0
*
* Notes:
* - For details on using the ADC device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/adc/adc
* - The ADC pins are defined in adc_config.h.
* - To view the corresponding pins and channels, refer to the GD32H759xx Datasheet.
*/
/*----------------------- ADC Driver configuration example ----------------------*/
/* #define BSP_USING_ADC0 */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- ADC CONFIG END --------------------------*/
/*-------------------------- DAC CONFIG BEGIN --------------------------*/
/** How to enable and configure DAC
*
* STEP 1, enable the DAC driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using DAC device drivers
*
* STEP 2, turn on the DAC instance by defining the related macro, and prefer the
* default board-level settings provided in dac_config.h.
* e.g. #define BSP_USING_DAC0
*
* STEP 3, if you accept the default pins in dac_config.h, you are done. No further
* pin configuration is required here.
*
* STEP 4, to override pins, set the port pins below for your MCU package according
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_DAC0_PIN "PA4"
* #define BSP_DAC0_CHANNEL DAC_OUT0
*
* Notes:
* - For details on using the DAC device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/dac/dac
* - If using the default configuration in dac_config.h, just add the device macro (e.g., BSP_USING_DAC0) in board.h.
* - To use custom pins, follow the definitions below.
*/
/*-----------------------DAC Driver configuration example ----------------------*/
/* #define BSP_USING_DAC0 */
/* #define BSP_DAC0_PIN "PA4" */
/* #define BSP_DAC0_CHANNEL DAC_OUT0 */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- DAC CONFIG END --------------------------*/
/*-------------------------- WDT CONFIG BEGIN --------------------------*/
/** How to enable and configure WDT
*
* STEP 1, enable the WDT driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using Watchdog device drivers
*
* Notes:
* - For details on using the WDT device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/watchdog/watchdog
*/
/*-------------------------- WDT CONFIG END --------------------------*/
/*-------------------------- HARDWARE TIMER CONFIG BEGIN --------------------------*/
/** if you want to use hardware timer you can use the following instructions.
*
* STEP 1, enable the hardware timer driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using hardware timer device drivers
*
* STEP 2, define macro related to the hwtimer
* such as #define BSP_USING_HWTIMER0
*
* Notes:
* - The macro definitions and device names for the hardware timer are defined in drv_hwtimer.c.
* - For details on using the hardware timer device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/hwtimer/hwtimer
*/
/*-----------------------HARDWARE TIMER configuration example ----------------------*/
/* #define BSP_USING_HWTIMER0 */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- HARDWARE TIMER CONFIG END --------------------------*/
/*-------------------------- RTC CONFIG BEGIN --------------------------*/
/** How to enable and configure RTC
*
* STEP 1, enable the RTC driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using RTC device drivers
*
* STEP 2, define macro related to the RTC
* such as #define BSP_USING_ALARM0
*
* Notes:
* - The macro definitions and device names for the RTC are defined in drv_rtc.c.
* - For details on using the RTC device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/rtc/rtc
*/
/*-----------------------RTC configuration example ----------------------*/
/* #define BSP_USING_ALARM0 */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- RTC CONFIG END --------------------------*/
/*-------------------------- SDIO CONFIG BEGIN --------------------------*/
/** How to enable and configure SDIO
* STEP 1, enable the SDIO driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using SD/EMMC device drivers
* STEP 2, enable the DFS driver in RT-Thread Settings.
* e.g. Components -> DFS -> Using DFS device drivers
* STEP 3, enable the elm-Fatfs driver in RT-Thread Settings.
* e.g. Components -> DFS -> Using elm-Fatfs device drivers
*
* Notes:
* - The SDIO pin configuration is implemented in the gpio_config() function
* located in drv_sdio.c.
* - Before using the SDIO interface, please consult the MCU datasheet and ensure
* that all related pins are configured according to the hardware requirements.
* - If custom pins are needed, update the configuration inside gpio_config()
* accordingly.
*/
/*-------------------------- SDIO CONFIG END --------------------------*/
/*-------------------------- CAN CONFIG BEGIN --------------------------*/
/** How to enable and configure CAN
*
* STEP 1, enable the CAN driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using CAN device drivers
*
* STEP 2, turn on the CAN instance by defining the related macro, and prefer the
* default board-level settings provided in can_config.h.
* e.g. #define BSP_USING_CAN0
*
* STEP 3, if you accept the default pins in can_config.h, you are done. No further
* pin configuration is required here.
*
* STEP 4, to override pins, set the port pins below for your MCU package according
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_CAN0_RX_PIN "PD0"
* #define BSP_CAN0_TX_PIN "PD1"
*
* STEP 5, to override alternate function (AF), set the AF macro below in this file
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions):
* e.g. #define BSP_CAN0_AFIO "AF9"
*
* Notes:
* - For details on using the CAN device, refer to the documentation center at the following link:
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/can/can
* - If using the default configuration in can_config.h, just add the device macro (e.g., BSP_USING_CAN0) in board.h.
* - To use custom pins, follow the definitions below.
*/
/*-----------------------CAN Driver configuration example ----------------------*/
/* #define BSP_USING_CAN0 */
/* #define BSP_CAN0_RX_PIN "PD0" */
/* #define BSP_CAN0_TX_PIN "PD1" */
/* #define BSP_CAN0_AFIO "AF9" */
/*---------- Configure your desired device here as described above ---------*/
/* USER CODE BEGIN */
/* USER CODE END */
/*-------------------------- CAN CONFIG END --------------------------*/
/*-------------------------- LCD CONFIG BEGIN --------------------------*/
/** How to enable and configure LCD
* STEP 1, enable the SDIO driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using LCD device drivers
*
* Notes:
* - The LCD pin configuration is implemented in the tli_gpio_config() function
* located in drv_lcd.c.
* - Before using the LCD, please consult the MCU datasheet and ensure that all
* related pins are configured according to the hardware requirements.
* - If custom pins are needed, update the configuration inside tli_gpio_config()
* accordingly.
*/
/*-------------------------- LCD CONFIG END --------------------------*/
/*-------------------------- ETH CONFIG BEGIN --------------------------*/
/** if you want to use eth you can use the following instructions.
*
* STEP 1, enable the network interface device in RT-Thread Settings.
* e.g. Components -> Network -> Enable network interface device
*
* STEP 2, enable the socket abstraction layer in RT-Thread Settings.
* e.g. Components -> Network -> SAL: socket abstraction layer
*
* STEP 3, select the lwip stack and features you need:
* e.g. Components -> Network -> LwIP: light weight TCP/IP stack
*
* STEP 4, configure MPU settings for Ethernet DMA descriptors and buffers:
* Check and modify the enet_mpu_config() function in drivers/drv_enet.c:
* - Configure MPU region for DMA descriptors and Rx/Tx buffers (0x30000000)
* - Set appropriate memory attributes (bufferable, non-cacheable, non-shareable)
* - Ensure MPU region size matches your actual buffer requirements
*
* STEP 5, configure Ethernet GPIO pins according to your hardware design:
* Check and modify the enet_gpio_config() function in drivers/rtt/include/config/enet_config.h:
* - Verify all MII/RMII/RGMII interface pins are correctly configured
* - Check clock output configuration (such as: PA8 for PHY reference clock)
* - Ensure correct alternate function (such as: AF11 for Ethernet pins)
* - Configure PHY reset pin if required by your hardware
*
* Notes:
* - The pin configuration in enet_gpio_config() must match your actual hardware design and PCB layout
* - MPU configuration in enet_mpu_config() is critical for proper DMA operation
* - For MII/RMII/RGMII interface, ensure all required pins are properly configured in enet_gpio_config()
* - Refer to GD32H7xx datasheet for Ethernet pin alternate function mapping
* - Refer to PHY chip datasheet for specific configuration requirements
*/
/*-------------------------- ETH CONFIG END --------------------------*/
/*-------------------------- USB HOST CONFIG BEGIN --------------------------*/
/** How to enable and configure USB Host (hardware)
*
* STEP 1, enable the USB Host driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using USB -> USB Host
*
* STEP 2, select the USB Host stack and drivers you need:
* e.g. USB Host -> Using USB Host
* USB Host -> Using USB Host -> Enable UDisk Drivers
* USB Host -> Using USB Host -> Enable HID Drivers
*
* STEP 3, define the basic USB configuration macros in board.h:
* e.g. #define BSP_USING_USB // Enable USB peripheral
* #define USE_USBHS0 // Enable USBHS0 instance
*
* STEP 4, select USB speed mode in board.h:
* For High Speed (HS) mode:
* e.g. #define USE_USB_HS
* For Full Speed (FS) mode:
* e.g. #define USE_USB_FS
*
* STEP 5, verify and modify the VBUS power switch configuration in the hardware driver:
* Check and modify the following definitions in drivers/usb/gd32h7_usb_hw.c:
* e.g. #define HOST_POWERSW_PORT_RCC RCU_GPIOG
* #define HOST_POWERSW_PORT GPIOG
* #define HOST_POWERSW_VBUS GPIO_PIN_7
* Ensure these definitions match your actual hardware design and pin connections.
*
* Notes:
* - USB HS (High Speed) requires external PHY and supports 480 Mbps data rate
* - USB FS (Full Speed) uses internal PHY and supports 12 Mbps data rate
* - The pin configuration depends on the specific USB instance (USBHS0/USBHS1) and package type
* - The HOST_POWERSW_VBUS configuration in gd32h7_usb_hw.c must match your actual hardware design
* - Refer to GD32H7xx datasheet for the specific pin alternate function mapping
*/
/*----------------------- Driver configuration example ----------------------*/
/* Basic USB configuration in board.h */
/* #define BSP_USING_USB */
/* #define USE_USBHS0 | #define USE_USBHS1 */
/* #define USE_USB_HS | #define USE_USB_FS */
/*-------------------------- USB HOST CONFIG END --------------------------*/
/*-------------------------- USB DEVICE CONFIG BEGIN --------------------------*/
/** How to enable and configure USB Device (hardware)
*
* STEP 1, enable the USB Device driver in RT-Thread Settings.
* e.g. Components -> Device Drivers -> Using USB -> USB Device
*
* STEP 2, select the USB Device stack and device classes you need:
* e.g. USB Device -> Using USB Device
* USB Device -> Using USB Device -> Enable CDC Virtual Com Port
* USB Device -> Using USB Device -> Enable Mass Storage Gadget
* USB Device -> Using USB Device -> Enable HID Gadget
* -> ...
*
* STEP 3, define the basic USB configuration macros in board.h:
* e.g. #define BSP_USING_USB // Enable USB peripheral
* #define USE_USBHS0 // Enable USBHS0 instance
*
* STEP 4, select USB speed mode in board.h:
* For High Speed (HS) mode:
* e.g. #define USE_USB_HS
* For Full Speed (FS) mode:
* e.g. #define USE_USB_FS
*
* Notes:
* - USB HS (High Speed) requires external PHY and supports 480 Mbps data rate
* - USB FS (Full Speed) uses internal PHY and supports 12 Mbps data rate
* - The pin configuration depends on the specific USB instance (USBHS0/USBHS1) and package type
* - The DEVICE_VBUS configuration in gd32h7_usb_hw.c must match your actual hardware design
* - For CDC Virtual Com Port, additional configurations may be needed in the device class settings
* - Refer to GD32H7xx datasheet for the specific pin alternate function mapping
*/
/*----------------------- Driver configuration example ----------------------*/
/* Basic USB configuration in board.h */
/* #define BSP_USING_USB */
/* #define USE_USBHS0 | #define USE_USBHS1 */
/* #define USE_USB_HS | #define USE_USB_FS */
/*-------------------------- USB DEVICE CONFIG END --------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_H__ */

286
828ECO/drivers/drv_adc.c

@ -0,0 +1,286 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-15 LZerro first version
* 2025-10-22 kurisaw optimize multi-channel GPIO configuration
*/
#include "drv_adc.h"
#include "adc_config.h"
#define DBG_TAG "drv.adc"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_ADC
#if defined(BSP_USING_ADC0)
struct rt_adc_device adc0;
#endif
#if defined(BSP_USING_ADC1)
struct rt_adc_device adc1;
#endif
#if defined(BSP_USING_ADC2)
struct rt_adc_device adc2;
#endif
static const struct gd32_adc adc_obj[] = {
#ifdef BSP_USING_ADC0
ADC0_CONFIG,
#endif
#ifdef BSP_USING_ADC1
ADC1_CONFIG,
#endif
#ifdef BSP_USING_ADC2
ADC2_CONFIG,
#endif
};
/**
* @brief ADC MSP Initialization
* This function configures the hardware resources.
* @param adc_clk, pin_name
* @retval None
*/
static void gd32_adc_gpio_init(rcu_periph_enum adc_clk, const char *pin_name)
{
rt_uint32_t port, pin;
rcu_periph_enum gpio_periph;
/* Skip if no valid pin name */
if (pin_name == RT_NULL || rt_strcmp(pin_name, "-1") == 0)
{
return;
}
/* Parse pin configuration */
if (get_pin_config(pin_name, &port, &pin, &gpio_periph) == -RT_ERROR)
{
LOG_E("Failed to get pin config for %s", pin_name);
return;
}
/* Enable ADC clock */
rcu_periph_clock_enable(adc_clk);
/* Enable GPIO clock */
rcu_periph_clock_enable(gpio_periph);
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E
/* Configure ADC pin as analog mode */
gpio_mode_set(port, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, pin);
#else
/* Configure ADC pin as analog input */
gpio_init(port, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, pin);
#endif
}
/**
* @brief ADC enable
* This function enables ADC.
* @param device, channel, enabled
* @retval None
*/
static rt_err_t gd32_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
{
uint32_t adc_periph;
struct gd32_adc *adc = (struct gd32_adc *)device->parent.user_data;
if (channel >= MAX_EXTERN_ADC_CHANNEL)
{
LOG_E("invalid channel");
return -RT_EINVAL;
}
adc_periph = (uint32_t)(adc->adc_periph);
if (enabled == ENABLE)
{
#if defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E
/* Disable ADC first */
adc_disable(adc_periph);
#endif
/* Initialize pin */
gd32_adc_gpio_init(adc->adc_clk, adc->adc_pins[channel]);
#if defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E
/* Configure clock, ADC0/1 max clock config 72M, ADC2 80M */
adc_clock_config(adc_periph, ADC_CLK_SYNC_HCLK_DIV6);
/* Set ADC resolution */
adc_resolution_config(adc_periph, ADC_RESOLUTION_12B);
#endif
/* Set ADC data alignment mode */
#if defined SOC_SERIES_GD32E23x
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
#else
adc_data_alignment_config(adc_periph, ADC_DATAALIGN_RIGHT);
#endif
/* Set as regular channel */
#if defined SOC_SERIES_GD32F4xx
adc_channel_length_config(adc_periph, ADC_ROUTINE_CHANNEL, 1);
adc_external_trigger_source_config(adc_periph, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_EXTI_11);
adc_external_trigger_config(adc_periph, ADC_ROUTINE_CHANNEL, ENABLE);
#elif defined SOC_SERIES_GD32H75E
adc_channel_length_config(adc_periph, ADC_ROUTINE_CHANNEL, 1);
adc_external_trigger_config(adc_periph, ADC_ROUTINE_CHANNEL, ENABLE);
#elif defined SOC_SERIES_GD32E23x
adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
#elif defined SOC_SERIES_GD32H7xx
adc_channel_length_config(adc_periph, ADC_REGULAR_CHANNEL, 1);
#else
adc_channel_length_config(adc_periph, ADC_REGULAR_CHANNEL, 1);
adc_external_trigger_source_config(adc_periph, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
adc_external_trigger_config(adc_periph, ADC_REGULAR_CHANNEL, ENABLE);
#endif
#if defined SOC_SERIES_GD32E23x
adc_enable();
#else
adc_enable(adc_periph);
#endif
/* Delay for ADC startup */
rt_thread_mdelay(1);
/* Calibrate ADC */
#if defined SOC_SERIES_GD32E23x
adc_calibration_enable();
#elif defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E
adc_calibration_mode_config(adc_periph, ADC_CALIBRATION_OFFSET);
adc_calibration_number(adc_periph, ADC_CALIBRATION_NUM1);
adc_calibration_enable(adc_periph);
#else
adc_calibration_enable(adc_periph);
#endif
}
else
{
#if defined SOC_SERIES_GD32E23x
adc_disable();
#else
adc_disable(adc_periph);
#endif
}
return RT_EOK;
}
/**
* @brief Convert ADC.
* This function gets ADC value.
* @param device, channel, value
* @retval None
*/
static rt_err_t gd32_adc_convert(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
{
uint32_t adc_periph;
uint32_t timeout = 0;
struct gd32_adc *adc = (struct gd32_adc *)(device->parent.user_data);
if (!value)
{
LOG_E("invalid param");
return -RT_EINVAL;
}
adc_periph = (uint32_t)(adc->adc_periph);
#if defined SOC_SERIES_GD32E23x
adc_flag_clear(ADC_FLAG_EOC | ADC_FLAG_STRC);
#else
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC);
#endif
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H75E
adc_routine_channel_config(adc_periph, 0, channel, 480);
adc_software_trigger_enable(adc_periph, ADC_ROUTINE_CHANNEL);
#elif defined SOC_SERIES_GD32E23x
adc_regular_channel_config(0, channel, ADC_SAMPLETIME_13POINT5);
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
#elif defined SOC_SERIES_GD32H7xx
adc_regular_channel_config(adc_periph, 0, channel, 480);
adc_software_trigger_enable(adc_periph, ADC_REGULAR_CHANNEL);
#else
adc_regular_channel_config(adc_periph, 0, channel, ADC_SAMPLETIME_13POINT5);
adc_software_trigger_enable(adc_periph, ADC_REGULAR_CHANNEL);
#endif
/* Wait for conversion complete */
#if defined SOC_SERIES_GD32E23x
while (!adc_flag_get(ADC_FLAG_EOC))
#else
while (!adc_flag_get(adc_periph, ADC_FLAG_EOC))
#endif
{
if (timeout >= 100)
{
#if defined SOC_SERIES_GD32E23x
adc_flag_clear(ADC_FLAG_EOC | ADC_FLAG_STRC);
#else
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC);
#endif
LOG_E("Convert Timeout");
return -RT_ETIMEOUT;
}
timeout++;
rt_thread_delay(1);
}
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H75E
*value = adc_routine_data_read(adc_periph);
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC);
#elif defined SOC_SERIES_GD32E23x
*value = adc_regular_data_read();
adc_flag_clear(ADC_FLAG_EOC | ADC_FLAG_STRC);
#else
*value = adc_regular_data_read(adc_periph);
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC);
#endif
return RT_EOK;
}
static struct rt_adc_ops gd32_adc_ops = {
.enabled = gd32_adc_enabled,
.convert = gd32_adc_convert,
};
static int rt_hw_adc_init(void)
{
int ret, i = 0;
syscfg_analog_switch_enable(SYSCFG_PA0_ANALOG_SWITCH);
syscfg_analog_switch_enable(SYSCFG_PA1_ANALOG_SWITCH);
syscfg_analog_switch_enable(SYSCFG_PC2_ANALOG_SWITCH);
syscfg_analog_switch_enable(SYSCFG_PC3_ANALOG_SWITCH);
for (; i < sizeof(adc_obj) / sizeof(adc_obj[0]); i++)
{
ret = rt_hw_adc_register(adc_obj[i].adc,
(const char *)adc_obj[i].device_name,
&gd32_adc_ops, &adc_obj[i]);
if (ret != RT_EOK)
{
/* TODO err handler */
LOG_E("failed register %s, err=%d", adc_obj[i].device_name, ret);
}
}
return ret;
}
INIT_BOARD_EXPORT(rt_hw_adc_init);
#endif

788
828ECO/drivers/drv_can.c

@ -0,0 +1,788 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-12-30 qingsong.yin first version
* 2024-03-07 qingsong.yin for CAN20kBaud/CAN10kBaud
* 2024-09-09 qingsong.yin for CANFD and DMA
* 2025-10-22 WangShun compatible with RT-Studio
*/
#include <stdlib.h>
#include "drv_can.h"
#include "can_config.h"
#ifdef RT_USING_CAN
#if defined(BSP_USING_CAN0) || defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2)
#define LOG_TAG "drv_can"
#include <drv_log.h>
#ifdef BSP_USING_CAN0
struct rt_can_device dev_can0;
#endif
#ifdef BSP_USING_CAN1
struct rt_can_device dev_can1;
#endif
#ifdef BSP_USING_CAN2
struct rt_can_device dev_can2;
#endif
static gd32_can_struct can_obj[] = {
#ifdef BSP_USING_CAN0
CAN0_CONFIG,
#endif
#ifdef BSP_USING_CAN1
CAN1_CONFIG,
#endif
#ifdef BSP_USING_CAN2
CAN2_CONFIG,
#endif
};
/* baud calculation example */
#if defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32H7xx) /* APB2 300MHz(max) */
static const struct gd32_baud_rate_tab can_baud_rate_tab[] = {
/* baud, sjw, prop, seg1, seg2, prescaler */
{ CAN1MBaud, 1, 20, 27, 12, 5 },
{ CAN800kBaud, 1, 2, 9, 3, 25 },
{ CAN500kBaud, 1, 2, 5, 2, 60 },
{ CAN250kBaud, 1, 2, 5, 2, 120 },
{ CAN125kBaud, 1, 2, 5, 2, 240 },
{ CAN100kBaud, 1, 2, 5, 2, 300 },
{ CAN50kBaud, 1, 2, 5, 2, 600 },
{ CAN20kBaud, 1, 14, 25, 10, 300 },
{ CAN10kBaud, 1, 14, 25, 10, 600 },
};
#ifdef RT_CAN_USING_CANFD
static const gd32_fd_data_baud_t can_fd_data_baud_tab[] = {
/* baud, sjw, prop, seg1, seg2, prescaler */
{ CANFD_5MBaud, 1, 2, 7, 2, 5 }, /* 5Mbps */
{ CANFD_4MBaud, 1, 3, 8, 3, 5 }, /* 4Mbps */
{ CANFD_3MBaud, 1, 4, 11, 4, 5 }, /* 3Mbps */
{ CANFD_2MBaud, 1, 6, 17, 6, 5 }, /* 2Mbps */
{ CANFD_1MBaud, 1, 20, 27, 12, 5 }, /* 1Mbps: Total Tq=60, SamplePoint≈80% */
{ CANFD_800kBaud, 1, 2, 9, 3, 25 }, /* 800kbps */
{ CANFD_500kBaud, 1, 2, 5, 2, 60 }, /* 500kbps */
{ CANFD_250kBaud, 1, 2, 5, 2, 120 }, /* 250kbps */
{ CANFD_125kBaud, 1, 2, 5, 2, 240 }, /* 125kbps */
{ CANFD_100kBaud, 1, 2, 5, 2, 300 }, /* 100kbps */
{ CANFD_50kBaud, 1, 2, 5, 2, 600 }, /* 50kbps */
{ CANFD_20kBaud, 1, 14, 25, 10, 300 }, /* 20kbps */
{ CANFD_10kBaud, 1, 14, 25, 10, 600 }, /* 10kbps */
};
#endif
#endif
static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
{
rt_uint32_t len, index;
len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
for (index = 0; index < len; index++)
{
if (can_baud_rate_tab[index].baud_rate == baud)
{
return index;
}
}
return 0; /* default baud is CAN1MBaud */
}
rt_weak void can_gpio_config(void)
{
int i;
rt_uint32_t tx_port, rx_port;
rt_uint32_t tx_pin, rx_pin;
rt_uint32_t pin_af;
rcu_periph_enum tx_periph, rx_periph;
#ifdef BSP_USING_CAN0
rcu_can_clock_config(IDX_CAN0, RCU_CANSRC_APB2);
rcu_periph_clock_enable(RCU_CAN0);
#endif
#ifdef BSP_USING_CAN1
rcu_can_clock_config(IDX_CAN1, RCU_CANSRC_APB2);
rcu_periph_clock_enable(RCU_CAN1);
#endif
#ifdef BSP_USING_CAN2
rcu_can_clock_config(IDX_CAN2, RCU_CANSRC_APB2);
rcu_periph_clock_enable(RCU_CAN2);
#endif
for (i = 0; i < sizeof(can_obj) / sizeof(can_obj[0]); i++)
{
get_pin_config(can_obj[i].tx_pin_name, &tx_port, &tx_pin, &tx_periph);
get_pin_config(can_obj[i].rx_pin_name, &rx_port, &rx_pin, &rx_periph);
pin_alternate_config(can_obj[i].alternate, &pin_af);
rcu_periph_clock_enable(tx_periph);
rcu_periph_clock_enable(rx_periph);
gpio_output_options_set(tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, tx_pin);
gpio_mode_set(tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, tx_pin);
gpio_af_set(tx_port, pin_af, tx_pin);
gpio_output_options_set(rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, rx_pin);
gpio_mode_set(rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, rx_pin);
gpio_af_set(rx_port, pin_af, rx_pin);
}
}
static rt_err_t gd32_can_configure(struct rt_can_device *can, struct can_configure *cfg)
{
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data;
rt_uint32_t baud_index;
RT_ASSERT(can);
RT_ASSERT(cfg);
RT_ASSERT(drv_can);
/* init can gpio and enable can clock */
can_gpio_config();
/* initialize CAN register */
can_deinit(drv_can->can_periph);
/* initialize CAN */
can_struct_para_init(CAN_INIT_STRUCT, &drv_can->can_init);
/* initialize CAN parameters */
drv_can->can_init.internal_counter_source = CAN_TIMER_SOURCE_BIT_CLOCK;
drv_can->can_init.self_reception = DISABLE;
drv_can->can_init.mb_tx_order = CAN_TX_HIGH_PRIORITY_MB_FIRST;
drv_can->can_init.mb_tx_abort_enable = ENABLE;
drv_can->can_init.local_priority_enable = DISABLE;
drv_can->can_init.mb_rx_ide_rtr_type = CAN_IDE_RTR_FILTERED;
drv_can->can_init.mb_remote_frame = CAN_STORE_REMOTE_REQUEST_FRAME;
drv_can->can_init.rx_private_filter_queue_enable = ENABLE;
drv_can->can_init.edge_filter_enable = DISABLE;
drv_can->can_init.protocol_exception_enable = DISABLE;
drv_can->can_init.rx_filter_order = CAN_RX_FILTER_ORDER_MAILBOX_FIRST;
drv_can->can_init.memory_size = CAN_MEMSIZE_32_UNIT;
/* filter configuration */
drv_can->can_init.mb_public_filter = 0U;
/* can baud config */
baud_index = get_can_baud_index(cfg->baud_rate);
drv_can->can_init.resync_jump_width = can_baud_rate_tab[baud_index].resync_jump_width;
drv_can->can_init.prop_time_segment = can_baud_rate_tab[baud_index].prop_time_segment;
drv_can->can_init.time_segment_1 = can_baud_rate_tab[baud_index].time_segment_1;
drv_can->can_init.time_segment_2 = can_baud_rate_tab[baud_index].time_segment_2;
drv_can->can_init.prescaler = can_baud_rate_tab[baud_index].prescaler;
if (can_init(drv_can->can_periph, &drv_can->can_init) != SUCCESS)
{
LOG_E("can init error");
return RT_ERROR;
}
#ifdef RT_CAN_USING_CANFD
/* Configure CANFD if enabled in user config */
drv_can->fd_enabled = 0;
can_struct_para_init(CAN_FD_INIT_STRUCT, &drv_can->can_fd_init);
if (cfg->enable_canfd)
{
/* default: enable bitrate switch and ISO mode */
drv_can->can_fd_init.bitrate_switch_enable = ENABLE;
drv_can->can_fd_init.iso_can_fd_enable = ENABLE;
/* select mailbox data size according to arbitration len requirement; default 64 bytes */
drv_can->can_fd_init.mailbox_data_size = CAN_MAILBOX_DATA_SIZE_8_BYTES;
drv_can->can_fd_init.tdc_enable = DISABLE;
drv_can->can_fd_init.tdc_offset = 0U;
if (cfg->use_bit_timing)
{
/* Arbitration timing has been already applied by classic init; now apply data phase */
drv_can->can_fd_init.resync_jump_width = cfg->canfd_timing.num_sjw;
drv_can->can_fd_init.prop_time_segment = cfg->canfd_timing.num_sspoff; /* heuristic if library expects prop vs seg1 */
drv_can->can_fd_init.time_segment_1 = cfg->canfd_timing.num_seg1;
drv_can->can_fd_init.time_segment_2 = cfg->canfd_timing.num_seg2;
drv_can->can_fd_init.prescaler = cfg->canfd_timing.prescaler;
}
else if (cfg->baud_rate_fd)
{
/* Simple reuse arbitration timing table for data speed if user sets baud_rate_fd as multiple (rough placeholder) */
/* NOTE: For precise FD data phase user should set use_bit_timing */
drv_can->can_fd_init.resync_jump_width = 1;
drv_can->can_fd_init.prop_time_segment = 2;
drv_can->can_fd_init.time_segment_1 = 5;
drv_can->can_fd_init.time_segment_2 = 2;
drv_can->can_fd_init.prescaler = 15; /* placeholder from example */
}
can_fd_config(drv_can->can_periph, &drv_can->can_fd_init);
drv_can->fd_enabled = 1;
}
#else
#ifdef RT_CAN_USING_HDR
/* Rxfifo configuration */
drv_can->can_fifo.dma_enable = DISABLE;
drv_can->can_fifo.filter_format_and_number = CAN_RXFIFO_FILTER_A_NUM_40;
drv_can->can_fifo.fifo_public_filter = 0;
can_rx_fifo_config(drv_can->can_periph, &drv_can->can_fifo);
#endif
#endif /* RT_CAN_USING_CANFD */
for (uint8_t i = 0; i < 16; i++)
{
can_struct_para_init(CAN_MDSC_STRUCT, &drv_can->rx_message[i]);
drv_can->rx_message[i].rtr = 0U;
drv_can->rx_message[i].ide = 0U;
drv_can->rx_message[i].code = CAN_MB_RX_STATUS_EMPTY;
/* rx mailbox */
drv_can->rx_message[i].id = 0x55U;
#if defined(SOC_SERIES_GD32H7xx)
drv_can->rx_message[i].data = (uint32_t *)(drv_can->fd_rx_buf[i]);
#elif defined(SOC_SERIES_GD32H75E)
memcpy(drv_can->rx_message[i].data, drv_can->fd_rx_buf[i], sizeof(drv_can->rx_message[i].data));
#endif
can_mailbox_config(drv_can->can_periph, i, &drv_can->rx_message[i]);
}
/* clear msg16-31 for tx */
CAN_STAT(drv_can->can_periph) = BITS(16, 31);
/* can mode config */
switch (cfg->mode)
{
case RT_CAN_MODE_NORMAL:
drv_can->mode = CAN_NORMAL_MODE;
break;
case RT_CAN_MODE_LISTEN:
drv_can->mode = CAN_MONITOR_MODE;
break;
case RT_CAN_MODE_LOOPBACK:
drv_can->mode = CAN_LOOPBACK_SILENT_MODE;
break;
case RT_CAN_MODE_LOOPBACKANLISTEN:
drv_can->mode = CAN_LOOPBACK_SILENT_MODE;
break;
default:
drv_can->mode = CAN_NORMAL_MODE;
break;
}
can_operation_mode_enter(drv_can->can_periph, drv_can->mode);
return RT_EOK;
}
static rt_err_t gd32_can_control(struct rt_can_device *can, int cmd, void *arg)
{
rt_uint32_t baud_index;
rt_uint32_t argval;
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data;
RT_ASSERT(can != RT_NULL);
RT_ASSERT(drv_can != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
argval = (rt_uint32_t)arg;
if (argval == RT_DEVICE_FLAG_INT_RX)
{
CAN_INTEN(drv_can->can_periph) &= ~BITS(0, 15);
if (CAN0 == drv_can->can_periph)
{
nvic_irq_disable(CAN0_RX_IRQn);
}
else if (CAN1 == drv_can->can_periph)
{
nvic_irq_disable(CAN1_RX_IRQn);
}
else if (CAN2 == drv_can->can_periph)
{
nvic_irq_disable(CAN2_RX_IRQn);
}
else
{
/* not reach */
}
}
else if (argval == RT_DEVICE_FLAG_INT_TX)
{ //int tx
CAN_INTEN(drv_can->can_periph) &= ~BITS(15, 31);
if (CAN0 == drv_can->can_periph)
{
nvic_irq_disable(CAN0_TX_IRQn);
}
else if (CAN1 == drv_can->can_periph)
{
nvic_irq_disable(CAN1_TX_IRQn);
}
else if (CAN2 == drv_can->can_periph)
{
nvic_irq_disable(CAN2_TX_IRQn);
}
else
{
/* not reach */
}
}
else if (argval == RT_DEVICE_CAN_INT_ERR)
{ //int error
can_interrupt_disable(drv_can->can_periph, CAN_INT_ERR_SUMMARY);
if (CAN0 == drv_can->can_periph)
{
nvic_irq_disable(CAN0_Error_IRQn);
}
else if (CAN1 == drv_can->can_periph)
{
nvic_irq_disable(CAN1_Error_IRQn);
}
else if (CAN2 == drv_can->can_periph)
{
nvic_irq_disable(CAN2_Error_IRQn);
}
else
{
/* not reach */
}
}
break;
case RT_DEVICE_CTRL_SET_INT:
argval = (rt_uint32_t)arg;
if (argval == RT_DEVICE_FLAG_INT_RX)
{
CAN_INTEN(drv_can->can_periph) |= BITS(0, 15);
if (CAN0 == drv_can->can_periph)
{
nvic_irq_enable(CAN0_RX_IRQn, 15, 0);
}
else if (CAN1 == drv_can->can_periph)
{
nvic_irq_enable(CAN1_RX_IRQn, 15, 0);
}
else if (CAN2 == drv_can->can_periph)
{
nvic_irq_enable(CAN2_RX_IRQn, 15, 0);
}
else
{
/* not reach */
}
}
else if (argval == RT_DEVICE_FLAG_INT_TX)
{
CAN_INTEN(drv_can->can_periph) |= BITS(16, 31);
if (CAN0 == drv_can->can_periph)
{
nvic_irq_enable(CAN0_TX_IRQn, 15, 0);
}
else if (CAN1 == drv_can->can_periph)
{
nvic_irq_enable(CAN1_TX_IRQn, 15, 0);
}
else if (CAN2 == drv_can->can_periph)
{
nvic_irq_enable(CAN2_TX_IRQn, 15, 0);
}
else
{
/* not reach */
}
}
else if (argval == RT_DEVICE_CAN_INT_ERR)
{
can_interrupt_enable(drv_can->can_periph, CAN_INT_ERR_SUMMARY);
if (CAN0 == drv_can->can_periph)
{
nvic_irq_enable(CAN0_ERROR_IRQn, 15, 0);
}
else if (CAN1 == drv_can->can_periph)
{
nvic_irq_enable(CAN1_ERROR_IRQn, 15, 0);
}
else if (CAN2 == drv_can->can_periph)
{
nvic_irq_enable(CAN2_ERROR_IRQn, 15, 0);
}
else
{
/* not reach */
}
}
break;
case RT_CAN_CMD_SET_FILTER:
{
drv_can->filter_cb = (void (*)(uint32_t can_periph))arg;
if (drv_can->filter_cb)
{
drv_can->filter_cb(drv_can->can_periph);
}
#ifdef RT_CAN_USING_HDR
struct rt_can_filter_config *filter_cfg;
filter_cfg = (struct rt_can_filter_config *)arg;
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE);
CAN_RFIFOPUBF(drv_can->can_periph) = 0xFFFFFFFF;
for (i = 0; i < 16; i++)
{
can_private_filter_config(drv_can->can_periph, i, 0xFFFFFFFF);
}
for (i = 0; i < filter_cfg->count; i++)
{
if (filter_cfg->items[i].hdr_bank == -1)
{
can_private_filter_config(drv_can->can_periph, i, filter_cfg->items[i].mask);
drv_can->fifo_element[i].extended_frame = filter_cfg->items[i].ide;
drv_can->fifo_element[i].remote_frame = filter_cfg->items[i].rtr;
drv_can->fifo_element[i].id = filter_cfg->items[i].id;
}
else
{
can_private_filter_config(drv_can->can_periph, filter_cfg->items[i].hdr_bank, filter_cfg->items[i].mask);
drv_can->fifo_element[filter_cfg->items[i].hdr_bank].extended_frame = filter_cfg->items[i].ide;
drv_can->fifo_element[filter_cfg->items[i].hdr_bank].remote_frame = filter_cfg->items[i].rtr;
drv_can->fifo_element[filter_cfg->items[i].hdr_bank].id = filter_cfg->items[i].id;
}
}
can_rx_fifo_filter_table_config(drv_can->can_periph, drv_can->fifo_element);
can_rx_fifo_clear(drv_can->can_periph);
can_operation_mode_enter(drv_can->can_periph, drv_can->mode);
#endif
}
break;
case RT_CAN_CMD_SET_MODE:
argval = (rt_uint32_t)arg;
if (argval != drv_can->device->config.mode)
{
/* can mode config */
switch (argval)
{
case RT_CAN_MODE_NORMAL:
drv_can->mode = CAN_NORMAL_MODE;
break;
case RT_CAN_MODE_LISTEN:
drv_can->mode = CAN_MONITOR_MODE;
break;
case RT_CAN_MODE_LOOPBACK:
drv_can->mode = CAN_LOOPBACK_SILENT_MODE;
break;
case RT_CAN_MODE_LOOPBACKANLISTEN:
drv_can->mode = CAN_LOOPBACK_SILENT_MODE;
break;
default:
return RT_ERROR;
break;
}
if (SUCCESS == can_operation_mode_enter(drv_can->can_periph, drv_can->mode))
{
return RT_EOK;
}
else
{
return RT_ERROR;
}
}
break;
case RT_CAN_CMD_SET_BAUD:
argval = (rt_uint32_t)arg;
if (argval != CAN1MBaud &&
argval != CAN800kBaud &&
argval != CAN500kBaud &&
argval != CAN250kBaud &&
argval != CAN125kBaud &&
argval != CAN100kBaud &&
argval != CAN50kBaud &&
argval != CAN20kBaud &&
argval != CAN10kBaud)
{
return -RT_ERROR;
}
if (argval != drv_can->device->config.baud_rate)
{
baud_index = get_can_baud_index(argval);
drv_can->can_init.resync_jump_width = can_baud_rate_tab[baud_index].resync_jump_width;
drv_can->can_init.prop_time_segment = can_baud_rate_tab[baud_index].prop_time_segment;
drv_can->can_init.time_segment_1 = can_baud_rate_tab[baud_index].time_segment_1;
drv_can->can_init.time_segment_2 = can_baud_rate_tab[baud_index].time_segment_2;
drv_can->can_init.prescaler = can_baud_rate_tab[baud_index].prescaler;
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE);
CAN_BT(drv_can->can_periph) &= ~(CAN_BT_BAUDPSC | CAN_BT_SJW | CAN_BT_PTS | CAN_BT_PBS1 | CAN_BT_PBS2);
CAN_BT(drv_can->can_periph) |= (uint32_t)(BT_BAUDPSC(drv_can->can_init.prescaler - 1U) |
BT_SJW((uint32_t)drv_can->can_init.resync_jump_width - 1U) |
BT_PTS((uint32_t)drv_can->can_init.prop_time_segment - 1U) |
BT_PBS1((uint32_t)drv_can->can_init.time_segment_1 - 1U) |
BT_PBS2((uint32_t)drv_can->can_init.time_segment_2 - 1U));
can_operation_mode_enter(drv_can->can_periph, drv_can->mode);
}
break;
case RT_CAN_CMD_SET_PRIV:
{
}
break;
case RT_CAN_CMD_GET_STATUS:
{
}
break;
#ifdef RT_CAN_USING_CANFD
case RT_CAN_CMD_SET_CANFD:
{
/* enable or disable CANFD dynamically */
rt_uint32_t enable = (rt_uint32_t)arg;
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE);
if (enable)
{
drv_can->fd_enabled = 1;
drv_can->can_fd_init.bitrate_switch_enable = ENABLE;
drv_can->can_fd_init.iso_can_fd_enable = ENABLE;
drv_can->can_fd_init.mailbox_data_size = CAN_MAILBOX_DATA_SIZE_16_BYTES;
drv_can->can_fd_init.tdc_enable = DISABLE;
drv_can->can_fd_init.tdc_offset = 0U;
can_fd_config(drv_can->can_periph, &drv_can->can_fd_init);
}
else
{
/* no direct API to disable FD; re-init classic CAN */
drv_can->fd_enabled = 0;
}
can_operation_mode_enter(drv_can->can_periph, drv_can->mode);
}
break;
case RT_CAN_CMD_SET_BAUD_FD:
{
rt_uint32_t data_baud;
int found;
unsigned k;
data_baud = (rt_uint32_t)arg;
if (!drv_can->fd_enabled || data_baud == 0)
break;
found = -1;
for (k = 0; k < (sizeof(can_fd_data_baud_tab) / sizeof(can_fd_data_baud_tab[0])); k++)
{
if (can_fd_data_baud_tab[k].baud == data_baud)
{
found = (int)k;
break;
}
}
if (found < 0)
break; /* unsupported */
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE);
drv_can->can_fd_init.resync_jump_width = can_fd_data_baud_tab[found].sjw;
drv_can->can_fd_init.prop_time_segment = can_fd_data_baud_tab[found].prop;
drv_can->can_fd_init.time_segment_1 = can_fd_data_baud_tab[found].seg1;
drv_can->can_fd_init.time_segment_2 = can_fd_data_baud_tab[found].seg2;
drv_can->can_fd_init.prescaler = can_fd_data_baud_tab[found].prescaler;
can_fd_config(drv_can->can_periph, &drv_can->can_fd_init);
can_operation_mode_enter(drv_can->can_periph, drv_can->mode);
}
break;
#endif /* RT_CAN_USING_CANFD */
}
return RT_EOK;
}
static rt_ssize_t gd32_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
{
uint8_t i = 0;
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data;
struct rt_can_msg *tx_msg = (struct rt_can_msg *)buf;
RT_ASSERT(can != RT_NULL);
RT_ASSERT(buf != RT_NULL);
RT_ASSERT(drv_can != RT_NULL);
RT_ASSERT(tx_msg != RT_NULL);
/* transmit message */
for (i = 16; i < 31; i++)
{
if (0U == (CAN_STAT(drv_can->can_periph) & BIT(i)))
{
/* initialize transmit message */
drv_can->tx_message[i].rtr = tx_msg->rtr;
drv_can->tx_message[i].ide = tx_msg->ide;
drv_can->tx_message[i].esi = 0U;
drv_can->tx_message[i].code = CAN_MB_TX_STATUS_DATA;
drv_can->tx_message[i].brs = tx_msg->brs;
drv_can->tx_message[i].fdf = tx_msg->fd_frame;
drv_can->tx_message[i].prio = tx_msg->priv;
drv_can->tx_message[i].data_bytes = tx_msg->len; /* classic frame length or already set for FD */
#if defined(SOC_SERIES_GD32H7xx)
drv_can->tx_message[i].data = (uint32_t *)tx_msg->data;
#elif defined(SOC_SERIES_GD32H75E)
memcpy(drv_can->tx_message[i].data, tx_msg->data, sizeof(drv_can->tx_message[i].data));
#endif
drv_can->tx_message[i].id = tx_msg->id;
can_mailbox_config(drv_can->can_periph, i, &drv_can->tx_message[i]);
return RT_EOK;
}
}
return RT_EFULL;
}
static rt_ssize_t gd32_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
{
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data;
struct rt_can_msg *pmsg = (struct rt_can_msg *)buf;
RT_ASSERT(can);
RT_ASSERT(pmsg);
uint8_t i;
/* receive data */
for (i = 0; i < 16; i++)
{
if (drv_can->rx_message_valid[i] == 1)
{
drv_can->rx_message_valid[i] = 0;
pmsg->id = drv_can->rx_message[i].id;
pmsg->ide = drv_can->rx_message[i].ide;
pmsg->rtr = drv_can->rx_message[i].rtr;
pmsg->len = drv_can->rx_message[i].data_bytes;
pmsg->priv = 0;
pmsg->hdr_index = i;
#ifdef RT_CAN_USING_CANFD
pmsg->fd_frame = drv_can->rx_message[i].fdf;
pmsg->brs = drv_can->rx_message[i].brs;
#endif
rt_memcpy(pmsg->data, drv_can->rx_message[i].data, pmsg->len);
return RT_EOK;
}
}
return RT_EEMPTY;
}
static const struct rt_can_ops _can_ops = {
gd32_can_configure,
gd32_can_control,
gd32_can_sendmsg,
gd32_can_recvmsg,
};
static void _can_rx_tx_isr(struct rt_can_device *can)
{
uint8_t i;
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data;
RT_ASSERT(can != RT_NULL);
RT_ASSERT(drv_can != RT_NULL);
for (i = 0; i < 16; i++)
{
if (CAN_STAT(drv_can->can_periph) & BIT(i))
{
can_mailbox_receive_data_read(drv_can->can_periph, i, &drv_can->rx_message[i]);
drv_can->rx_message_valid[i] = 1;
rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND);
CAN_STAT(drv_can->can_periph) = BIT(i); /* Clear the status bit */
}
}
for (i = 16; i < 31; i++)
{
if (0U != (CAN_STAT(drv_can->can_periph) & BIT(i)))
{
CAN_STAT(drv_can->can_periph) = BIT(i);
rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE);
return;
}
}
}
static void _can_sce_isr(struct rt_can_device *can)
{
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data;
rt_uint32_t err_code;
RT_ASSERT(can != RT_NULL);
RT_ASSERT(drv_can != RT_NULL);
if (SET == can_interrupt_flag_get(drv_can->can_periph, CAN_INT_FLAG_ERR_SUMMARY))
{
can_interrupt_flag_clear(drv_can->can_periph, CAN_INT_FLAG_ERR_SUMMARY);
err_code = GET_BITS(CAN_ERR1(drv_can->can_periph), 10U, 15U);
if (err_code & CAN_ERR1_FMERR)
{
can->status.formaterrcnt++;
}
if (err_code & CAN_ERR1_CRCERR)
{
can->status.crcerrcnt++;
}
if (err_code & CAN_ERR1_ACKERR)
{
can->status.ackerrcnt++;
}
can->status.errcode = err_code;
}
}
#ifdef BSP_USING_CAN0
void CAN0_Message_IRQHandler(void)
{
rt_interrupt_enter();
_can_rx_tx_isr(&dev_can0);
rt_interrupt_leave();
}
void CAN0_Error_IRQHandler(void)
{
rt_interrupt_enter();
_can_sce_isr(&dev_can0);
rt_interrupt_leave();
}
#endif /* BSP_USING_CAN0 */
#ifdef BSP_USING_CAN1
void CAN1_Message_IRQHandler(void)
{
rt_interrupt_enter();
_can_rx_tx_isr(&dev_can1);
rt_interrupt_leave();
}
void CAN1_Error_IRQHandler(void)
{
rt_interrupt_enter();
_can_sce_isr(&dev_can1);
rt_interrupt_leave();
}
#endif /* BSP_USING_CAN1 */
#ifdef BSP_USING_CAN2
void CAN2_Message_IRQHandler(void)
{
rt_interrupt_enter();
_can_rx_tx_isr(&dev_can2);
rt_interrupt_leave();
}
void CAN2_Error_IRQHandler(void)
{
rt_interrupt_enter();
_can_sce_isr(&dev_can2);
rt_interrupt_leave();
}
#endif /* BSP_USING_CAN2 */
int rt_hw_can_init(void)
{
int i;
struct can_configure config = CANDEFAULTCONFIG;
config.privmode = RT_CAN_MODE_NOPRIV;
config.ticks = 50;
#ifdef RT_CAN_USING_HDR
config.maxhdr = 40;
#endif
for (i = 0; i < sizeof(can_obj) / sizeof(can_obj[0]); i++)
{
can_obj[i].device->config = config;
rt_hw_can_register(can_obj[i].device, can_obj[i].name, &_can_ops, &can_obj[i]);
}
return 0;
}
INIT_BOARD_EXPORT(rt_hw_can_init);
#endif /* defined(BSP_USING_CAN0) || defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2) */
#endif /*RT_USING_CAN*/

107
828ECO/drivers/drv_common.c

@ -0,0 +1,107 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-7 SummerGift first version
*/
#include "drv_common.h"
#include "board.h"
#ifdef RT_USING_SERIAL
#ifdef RT_USING_SERIAL_V2
#include "drv_usart_v2.h"
#else
#include "drv_usart.h"
#endif /* RT_USING_SERIAL */
#endif /* RT_USING_SERIAL_V2 */
#define DBG_TAG "drv_common"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
static void reboot(uint8_t argc, char **argv)
{
rt_hw_cpu_reset();
}
MSH_CMD_EXPORT(reboot, Reboot System);
#endif /* RT_USING_FINSH */
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
while (1)
{
}
/* USER CODE END Error_Handler */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
}
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
/**
* This function will initial gd32 board.
*/
void hw_board_init()
{
/* NVIC Configuration */
#define NVIC_VTOR_MASK 0x3FFFFF80
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x10000000 */
SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK);
#endif
/* Enable IChace */
SCB_EnableICache();
/* Enable DChace */
SCB_EnableDCache();
SystemClock_Config();
/* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
extern int rt_hw_pin_init(void);
rt_hw_pin_init();
#endif
/* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
extern int rt_hw_usart_init(void);
rt_hw_usart_init();
#endif
}

218
828ECO/drivers/drv_dac.c

@ -0,0 +1,218 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-11 kurisaw first version
*/
#include "drv_dac.h"
#include "dac_config.h"
#ifdef RT_USING_DAC
#define DBG_TAG "drv.dac"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static struct gd32_dac gd32_dac_obj[] = {
#ifdef BSP_USING_DAC0
DAC0_CONFIG,
#endif
#ifdef BSP_USING_DAC1
DAC1_CONFIG,
#endif
};
/* DAC initialization status */
typedef struct
{
uint32_t dac_periph;
rt_bool_t initialized;
} DAC_INIT_STATUS;
static DAC_INIT_STATUS dac_init_status[] = {
#if defined(DAC0)
{ DAC0, RT_FALSE },
#elif defined(DAC1)
{ DAC1, RT_FALSE },
#endif
};
/* Private functions */
static void gd32_dac_hw_init(struct gd32_dac *gd32_dac)
{
rt_uint32_t dac_port, dac_pin;
rcu_periph_enum dac_periph;
/* Get pin configuration */
if (get_pin_config(gd32_dac->pin_name, &dac_port, &dac_pin, &dac_periph) == -RT_ERROR)
{
LOG_E("Failed to get pin config for %s", gd32_dac->pin_name);
return;
}
/* Enable clocks */
rcu_periph_clock_enable(RCU_DAC);
rcu_periph_clock_enable(dac_periph);
/* Configure GPIO as analog mode for DAC output */
gpio_mode_set(dac_port, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, dac_pin);
LOG_D("DAC GPIO %s configured", gd32_dac->pin_name);
}
static void dac_initialize(uint32_t dac_periph)
{
/* Check if DAC is already initialized */
for (int i = 0; i < sizeof(dac_init_status) / sizeof(dac_init_status[0]); i++)
{
if (dac_init_status[i].dac_periph == dac_periph && !dac_init_status[i].initialized)
{
/* Initialize DAC */
dac_deinit(dac_periph);
/* DAC trigger disable for both channels */
dac_trigger_disable(dac_periph, gd32_dac_obj[i].channel);
/* DAC wave mode disable for both channels */
dac_wave_mode_config(dac_periph, gd32_dac_obj[i].channel, DAC_WAVE_DISABLE);
#if defined(SOC_SERIES_GD32F10x) || defined(SOC_SERIES_GD32F20x) || defined(SOC_SERIES_GD32F30x) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32E50x)
/* DAC output buffer enable */
dac_output_buffer_enable(dac_periph, gd32_dac_obj[i].channel);
#endif
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
/* DAC mode configuration - normal mode with buffer enabled */
dac_mode_config(dac_periph, gd32_dac_obj[i].channel, NORMAL_PIN_BUFFON);
#endif
dac_init_status[i].initialized = RT_TRUE;
break;
}
}
}
static rt_err_t drv_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
{
struct gd32_dac *dac_dev = (struct gd32_dac *)device;
/* Validate channel */
if (channel != DAC_OUT0 && channel != DAC_OUT1)
{
LOG_E("Invalid DAC channel: %d", channel);
return -RT_EINVAL;
}
/* Enable DAC channel */
dac_enable(dac_dev->dac_periph, (uint8_t)channel);
LOG_D("DAC %s channel %d enabled", dac_dev->name, channel);
return RT_EOK;
}
static rt_err_t drv_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
{
struct gd32_dac *dac_dev = (struct gd32_dac *)device;
/* Validate channel */
if (channel != DAC_OUT0 && channel != DAC_OUT1)
{
LOG_E("Invalid DAC channel: %d", channel);
return -RT_EINVAL;
}
/* Disable DAC channel */
dac_disable(dac_dev->dac_periph, (uint8_t)channel);
LOG_D("DAC %s channel %d disabled", dac_dev->name, channel);
return RT_EOK;
}
static rt_err_t drv_dac_convert(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
struct gd32_dac *dac_dev = (struct gd32_dac *)device;
if (value == RT_NULL)
{
LOG_E("DAC value pointer is NULL");
return -RT_EINVAL;
}
/* Validate channel */
if (channel != DAC_OUT0 && channel != DAC_OUT1)
{
LOG_E("Invalid DAC channel: %d", channel);
return -RT_EINVAL;
}
/* Check value range for 12-bit DAC */
if (*value > 4095)
{
LOG_E("DAC value %u exceeds maximum 4095", *value);
return -RT_EINVAL;
}
/* Set DAC data with 12-bit right aligned */
dac_data_set(dac_dev->dac_periph, (uint8_t)channel, DAC_ALIGN_12B_R, (uint16_t)(*value));
LOG_D("DAC %s channel %d set to value %u", dac_dev->name, channel, *value);
return RT_EOK;
}
static rt_err_t drv_dac_set_mode(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t mode)
{
struct gd32_dac *dac_dev = (struct gd32_dac *)device;
if (channel != DAC_OUT0 && channel != DAC_OUT1)
{
return -RT_EINVAL;
}
dac_mode_config(dac_dev->dac_periph, channel, mode);
return RT_EOK;
}
static struct rt_dac_ops drv_ops = {
.disabled = drv_dac_disabled,
.enabled = drv_dac_enabled,
.convert = drv_dac_convert,
};
static int drv_dac_init(void)
{
int i, result = RT_EOK;
for (i = 0; i < sizeof(gd32_dac_obj) / sizeof(gd32_dac_obj[0]); i++)
{
/* Initialize DAC hardware - GPIO configuration */
gd32_dac_hw_init(&gd32_dac_obj[i]);
/* Initialize DAC peripheral if not already initialized */
dac_initialize(gd32_dac_obj[i].dac_periph);
/* Register DAC device */
if (rt_hw_dac_register(&gd32_dac_obj[i].dac_device, gd32_dac_obj[i].name,
&drv_ops, RT_NULL) == RT_EOK)
{
LOG_D("%s register success (channel %d)",
gd32_dac_obj[i].name, gd32_dac_obj[i].channel);
}
else
{
LOG_E("%s register failed", gd32_dac_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_DEVICE_EXPORT(drv_dac_init);
#endif /* RT_USING_DAC */

1192
828ECO/drivers/drv_enet.c

File diff suppressed because it is too large

945
828ECO/drivers/drv_gpio.c

@ -0,0 +1,945 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include <rtdevice.h>
#include <rthw.h>
#include <rtconfig.h>
#include <stdlib.h>
#ifdef RT_USING_PIN
#include "drv_gpio.h"
static const struct pin_index pins[] = {
#ifdef GPIOA
GD32_PIN(0, A, 0),
GD32_PIN(1, A, 1),
GD32_PIN(2, A, 2),
GD32_PIN(3, A, 3),
GD32_PIN(4, A, 4),
GD32_PIN(5, A, 5),
GD32_PIN(6, A, 6),
GD32_PIN(7, A, 7),
GD32_PIN(8, A, 8),
GD32_PIN(9, A, 9),
GD32_PIN(10, A, 10),
GD32_PIN(11, A, 11),
GD32_PIN(12, A, 12),
GD32_PIN(13, A, 13),
GD32_PIN(14, A, 14),
GD32_PIN(15, A, 15),
#endif
#ifdef GPIOB
GD32_PIN(16, B, 0),
GD32_PIN(17, B, 1),
GD32_PIN(18, B, 2),
GD32_PIN(19, B, 3),
GD32_PIN(20, B, 4),
GD32_PIN(21, B, 5),
GD32_PIN(22, B, 6),
GD32_PIN(23, B, 7),
GD32_PIN(24, B, 8),
GD32_PIN(25, B, 9),
GD32_PIN(26, B, 10),
GD32_PIN(27, B, 11),
GD32_PIN(28, B, 12),
GD32_PIN(29, B, 13),
GD32_PIN(30, B, 14),
GD32_PIN(31, B, 15),
#endif
#ifdef GPIOC
GD32_PIN(32, C, 0),
GD32_PIN(33, C, 1),
GD32_PIN(34, C, 2),
GD32_PIN(35, C, 3),
GD32_PIN(36, C, 4),
GD32_PIN(37, C, 5),
GD32_PIN(38, C, 6),
GD32_PIN(39, C, 7),
GD32_PIN(40, C, 8),
GD32_PIN(41, C, 9),
GD32_PIN(42, C, 10),
GD32_PIN(43, C, 11),
GD32_PIN(44, C, 12),
GD32_PIN(45, C, 13),
GD32_PIN(46, C, 14),
GD32_PIN(47, C, 15),
#endif
#ifdef GPIOD
GD32_PIN(48, D, 0),
GD32_PIN(49, D, 1),
GD32_PIN(50, D, 2),
GD32_PIN(51, D, 3),
GD32_PIN(52, D, 4),
GD32_PIN(53, D, 5),
GD32_PIN(54, D, 6),
GD32_PIN(55, D, 7),
GD32_PIN(56, D, 8),
GD32_PIN(57, D, 9),
GD32_PIN(58, D, 10),
GD32_PIN(59, D, 11),
GD32_PIN(60, D, 12),
GD32_PIN(61, D, 13),
GD32_PIN(62, D, 14),
GD32_PIN(63, D, 15),
#endif
#ifdef GPIOE
GD32_PIN(64, E, 0),
GD32_PIN(65, E, 1),
GD32_PIN(66, E, 2),
GD32_PIN(67, E, 3),
GD32_PIN(68, E, 4),
GD32_PIN(69, E, 5),
GD32_PIN(70, E, 6),
GD32_PIN(71, E, 7),
GD32_PIN(72, E, 8),
GD32_PIN(73, E, 9),
GD32_PIN(74, E, 10),
GD32_PIN(75, E, 11),
GD32_PIN(76, E, 12),
GD32_PIN(77, E, 13),
GD32_PIN(78, E, 14),
GD32_PIN(79, E, 15),
#endif
#ifdef GPIOF
GD32_PIN(80, F, 0),
GD32_PIN(81, F, 1),
GD32_PIN(82, F, 2),
GD32_PIN(83, F, 3),
GD32_PIN(84, F, 4),
GD32_PIN(85, F, 5),
GD32_PIN(86, F, 6),
GD32_PIN(87, F, 7),
GD32_PIN(88, F, 8),
GD32_PIN(89, F, 9),
GD32_PIN(90, F, 10),
GD32_PIN(91, F, 11),
GD32_PIN(92, F, 12),
GD32_PIN(93, F, 13),
GD32_PIN(94, F, 14),
GD32_PIN(95, F, 15),
#endif
#ifdef GPIOG
GD32_PIN(96, G, 0),
GD32_PIN(97, G, 1),
GD32_PIN(98, G, 2),
GD32_PIN(99, G, 3),
GD32_PIN(100, G, 4),
GD32_PIN(101, G, 5),
GD32_PIN(102, G, 6),
GD32_PIN(103, G, 7),
GD32_PIN(104, G, 8),
GD32_PIN(105, G, 9),
GD32_PIN(106, G, 10),
GD32_PIN(107, G, 11),
GD32_PIN(108, G, 12),
GD32_PIN(109, G, 13),
GD32_PIN(110, G, 14),
GD32_PIN(111, G, 15),
#endif
#ifdef GPIOH
GD32_PIN(112, H, 0),
GD32_PIN(113, H, 1),
GD32_PIN(114, H, 2),
GD32_PIN(115, H, 3),
GD32_PIN(116, H, 4),
GD32_PIN(117, H, 5),
GD32_PIN(118, H, 6),
GD32_PIN(119, H, 7),
GD32_PIN(120, H, 8),
GD32_PIN(121, H, 9),
GD32_PIN(122, H, 10),
GD32_PIN(123, H, 11),
GD32_PIN(124, H, 12),
GD32_PIN(125, H, 13),
GD32_PIN(126, H, 14),
GD32_PIN(127, H, 15),
#endif
#ifdef GPIOI
GD32_PIN(128, I, 0),
GD32_PIN(129, I, 1),
GD32_PIN(130, I, 2),
GD32_PIN(131, I, 3),
GD32_PIN(132, I, 4),
GD32_PIN(133, I, 5),
GD32_PIN(134, I, 6),
GD32_PIN(135, I, 7),
GD32_PIN(136, I, 8),
GD32_PIN(137, I, 9),
GD32_PIN(138, I, 10),
GD32_PIN(139, I, 11),
GD32_PIN(140, I, 12),
GD32_PIN(141, I, 13),
GD32_PIN(142, I, 14),
GD32_PIN(143, I, 15),
#endif
};
#if defined SOC_SERIES_GD32E23x
static const struct pin_irq_map pin_irq_map[] = {
{ GPIO_PIN_0, EXTI0_1_IRQn },
{ GPIO_PIN_1, EXTI0_1_IRQn },
{ GPIO_PIN_2, EXTI2_3_IRQn },
{ GPIO_PIN_3, EXTI2_3_IRQn },
{ GPIO_PIN_4, EXTI4_15_IRQn },
{ GPIO_PIN_5, EXTI4_15_IRQn },
{ GPIO_PIN_6, EXTI4_15_IRQn },
{ GPIO_PIN_7, EXTI4_15_IRQn },
{ GPIO_PIN_8, EXTI4_15_IRQn },
{ GPIO_PIN_9, EXTI4_15_IRQn },
{ GPIO_PIN_10, EXTI4_15_IRQn },
{ GPIO_PIN_11, EXTI4_15_IRQn },
{ GPIO_PIN_12, EXTI4_15_IRQn },
{ GPIO_PIN_13, EXTI4_15_IRQn },
{ GPIO_PIN_14, EXTI4_15_IRQn },
{ GPIO_PIN_15, EXTI4_15_IRQn },
};
#else
static const struct pin_irq_map pin_irq_map[] = {
{ GPIO_PIN_0, EXTI0_IRQn },
{ GPIO_PIN_1, EXTI1_IRQn },
{ GPIO_PIN_2, EXTI2_IRQn },
{ GPIO_PIN_3, EXTI3_IRQn },
{ GPIO_PIN_4, EXTI4_IRQn },
{ GPIO_PIN_5, EXTI5_9_IRQn },
{ GPIO_PIN_6, EXTI5_9_IRQn },
{ GPIO_PIN_7, EXTI5_9_IRQn },
{ GPIO_PIN_8, EXTI5_9_IRQn },
{ GPIO_PIN_9, EXTI5_9_IRQn },
{ GPIO_PIN_10, EXTI10_15_IRQn },
{ GPIO_PIN_11, EXTI10_15_IRQn },
{ GPIO_PIN_12, EXTI10_15_IRQn },
{ GPIO_PIN_13, EXTI10_15_IRQn },
{ GPIO_PIN_14, EXTI10_15_IRQn },
{ GPIO_PIN_15, EXTI10_15_IRQn },
};
#endif
struct rt_pin_irq_hdr pin_irq_hdr_tab[] = {
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
{ -1, 0, RT_NULL, RT_NULL },
};
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
/**
* @brief get pin
* @param pin
* @retval None
*/
const struct pin_index *get_pin(rt_uint8_t pin)
{
const struct pin_index *index;
if (pin < ITEM_NUM(pins))
{
index = &pins[pin];
if (index->index == -1)
index = RT_NULL;
}
else
{
index = RT_NULL;
}
return index;
}
int get_pin_config(const char *pin_name, uint32_t *port, uint32_t *pin, rcu_periph_enum *clk)
{
if (pin_name == NULL || port == NULL || pin == NULL || clk == NULL)
{
return -RT_ERROR;
}
if (strlen(pin_name) < 3 || pin_name[0] != 'P')
{
return -RT_ERROR;
}
char port_letter = pin_name[1];
switch (port_letter)
{
#ifdef GPIOA
case 'A':
*port = GPIOA;
*clk = RCU_GPIOA;
break;
#endif /* GPIOA */
#ifdef GPIOB
case 'B':
*port = GPIOB;
*clk = RCU_GPIOB;
break;
#endif /* GPIOB */
#ifdef GPIOC
case 'C':
*port = GPIOC;
*clk = RCU_GPIOC;
break;
#endif /* GPIOC */
#ifdef GPIOD
case 'D':
*port = GPIOD;
*clk = RCU_GPIOD;
break;
#endif /* GPIOD */
#ifdef GPIOE
case 'E':
*port = GPIOE;
*clk = RCU_GPIOE;
break;
#endif /* GPIOE */
#ifdef GPIOF
case 'F':
*port = GPIOF;
*clk = RCU_GPIOF;
break;
#endif /* GPIOF */
#ifdef GPIOG
case 'G':
*port = GPIOG;
*clk = RCU_GPIOG;
break;
#endif /* GPIOG */
#ifdef GPIOH
case 'H':
*port = GPIOH;
*clk = RCU_GPIOH;
break;
#endif /* GPIOH */
#ifdef GPIOI
case 'I':
*port = GPIOI;
*clk = RCU_GPIOI;
break;
#endif /* GPIOI */
#ifdef GPIOJ
case 'J':
*port = GPIOJ;
*clk = RCU_GPIOJ;
break;
#endif /* GPIOJ */
#ifdef GPIOK
case 'K':
*port = GPIOK;
*clk = RCU_GPIOK;
break;
#endif /* GPIOK */
default:
return -RT_ERROR;
}
int pin_num = atoi(pin_name + 2);
if (pin_num < 0 || pin_num > 15)
{
return -RT_ERROR;
}
*pin = GPIO_PIN_0 << pin_num;
return 0;
}
int pin_alternate_config(const char *alternate, uint32_t *af)
{
if (alternate == NULL || af == NULL)
{
return -RT_ERROR;
}
if (alternate[0] != 'A' || alternate[1] != 'F')
{
return -RT_ERROR;
}
int af_num = atoi(alternate + 2);
if (af_num < 0 || af_num > 15)
{
return -RT_ERROR;
}
switch (af_num)
{
case 0:
*af = GPIO_AF_0;
break;
case 1:
*af = GPIO_AF_1;
break;
case 2:
*af = GPIO_AF_2;
break;
case 3:
*af = GPIO_AF_3;
break;
case 4:
*af = GPIO_AF_4;
break;
case 5:
*af = GPIO_AF_5;
break;
case 6:
*af = GPIO_AF_6;
break;
case 7:
*af = GPIO_AF_7;
break;
case 8:
*af = GPIO_AF_8;
break;
case 9:
*af = GPIO_AF_9;
break;
case 10:
*af = GPIO_AF_10;
break;
case 11:
*af = GPIO_AF_11;
break;
case 12:
*af = GPIO_AF_12;
break;
case 13:
*af = GPIO_AF_13;
break;
case 14:
*af = GPIO_AF_14;
break;
case 15:
*af = GPIO_AF_15;
break;
default:
return -RT_ERROR;
}
return 0;
}
/**
* @brief set pin mode
* @param dev, pin, mode
* @retval None
*/
static void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
{
const struct pin_index *index = RT_NULL;
rt_uint32_t pin_mode = 0;
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
rt_uint32_t pin_pupd = 0, pin_odpp = 0;
#endif
index = get_pin(pin);
if (index == RT_NULL)
{
return;
}
/* GPIO Periph clock enable */
rcu_periph_clock_enable(index->clk);
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
pin_mode = GPIO_MODE_OUTPUT;
#else
pin_mode = GPIO_MODE_OUT_PP;
#endif
switch (mode)
{
case PIN_MODE_OUTPUT:
/* output setting */
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
pin_mode = GPIO_MODE_OUTPUT;
pin_pupd = GPIO_PUPD_NONE;
pin_odpp = GPIO_OTYPE_PP;
#else
pin_mode = GPIO_MODE_OUT_PP;
#endif
break;
case PIN_MODE_OUTPUT_OD:
/* output setting: od. */
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
pin_mode = GPIO_MODE_OUTPUT;
pin_pupd = GPIO_PUPD_NONE;
pin_odpp = GPIO_OTYPE_OD;
#else
pin_mode = GPIO_MODE_OUT_OD;
#endif
break;
case PIN_MODE_INPUT:
/* input setting: not pull. */
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
pin_mode = GPIO_MODE_INPUT;
pin_pupd = GPIO_PUPD_PULLUP | GPIO_PUPD_PULLDOWN;
#else
pin_mode = GPIO_MODE_IN_FLOATING;
#endif
break;
case PIN_MODE_INPUT_PULLUP:
/* input setting: pull up. */
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
pin_mode = GPIO_MODE_INPUT;
pin_pupd = GPIO_PUPD_PULLUP;
#else
pin_mode = GPIO_MODE_IPU;
#endif
break;
case PIN_MODE_INPUT_PULLDOWN:
/* input setting: pull down. */
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
pin_mode = GPIO_MODE_INPUT;
pin_pupd = GPIO_PUPD_PULLDOWN;
#else
pin_mode = GPIO_MODE_IPD;
#endif
break;
default:
break;
}
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
gpio_mode_set(index->gpio_periph, pin_mode, pin_pupd, index->pin);
if (pin_mode == GPIO_MODE_OUTPUT)
{
gpio_output_options_set(index->gpio_periph, pin_odpp, GPIO_OSPEED_50MHZ, index->pin);
}
#elif defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E
gpio_mode_set(index->gpio_periph, pin_mode, pin_pupd, index->pin);
if (pin_mode == GPIO_MODE_OUTPUT)
{
gpio_output_options_set(index->gpio_periph, pin_odpp, GPIO_OSPEED_60MHZ, index->pin);
}
#else
gpio_init(index->gpio_periph, pin_mode, GPIO_OSPEED_50MHZ, index->pin);
#endif
}
/**
* @brief pin write
* @param dev, pin, valuie
* @retval None
*/
static void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
{
const struct pin_index *index = RT_NULL;
index = get_pin(pin);
if (index == RT_NULL)
{
return;
}
gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value);
}
/**
* @brief pin read
* @param dev, pin
* @retval None
*/
static rt_ssize_t gd32_pin_read(rt_device_t dev, rt_base_t pin)
{
rt_ssize_t value = PIN_LOW;
const struct pin_index *index = RT_NULL;
index = get_pin(pin);
if (index == RT_NULL)
{
return -RT_EINVAL;
}
value = gpio_input_bit_get(index->gpio_periph, index->pin);
return value;
}
/**
* @brief bit2bitno
* @param bit
* @retval None
*/
rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
{
rt_uint8_t i;
for (i = 0; i < 32; i++)
{
if ((0x01 << i) == bit)
{
return i;
}
}
return -1;
}
/**
* @brief pin write
* @param pinbit
* @retval None
*/
rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit)
{
rt_int32_t map_index = bit2bitno(pinbit);
if (map_index < 0 || map_index >= ITEM_NUM(pin_irq_map))
{
return RT_NULL;
}
return &pin_irq_map[map_index];
}
/**
* @brief pin irq attach
* @param device, pin, mode
* @retval None
*/
static rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_base_t pin,
rt_uint8_t mode, void (*hdr)(void *args), void *args)
{
const struct pin_index *index = RT_NULL;
rt_base_t level;
rt_int32_t hdr_index = -1;
index = get_pin(pin);
if (index == RT_NULL)
{
return -RT_EINVAL;
}
hdr_index = bit2bitno(index->pin);
if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
{
return -RT_EINVAL;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[hdr_index].pin == pin &&
pin_irq_hdr_tab[hdr_index].hdr == hdr &&
pin_irq_hdr_tab[hdr_index].mode == mode &&
pin_irq_hdr_tab[hdr_index].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
if (pin_irq_hdr_tab[hdr_index].pin != -1)
{
rt_hw_interrupt_enable(level);
return -RT_EFULL;
}
pin_irq_hdr_tab[hdr_index].pin = pin;
pin_irq_hdr_tab[hdr_index].hdr = hdr;
pin_irq_hdr_tab[hdr_index].mode = mode;
pin_irq_hdr_tab[hdr_index].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
/**
* @brief pin irq detach
* @param device, pin
* @retval None
*/
static rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_base_t pin)
{
const struct pin_index *index = RT_NULL;
rt_base_t level;
rt_int32_t hdr_index = -1;
index = get_pin(pin);
if (index == RT_NULL)
{
return -RT_EINVAL;
}
hdr_index = bit2bitno(index->pin);
if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
{
return -RT_EINVAL;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[hdr_index].pin == -1)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
pin_irq_hdr_tab[hdr_index].pin = -1;
pin_irq_hdr_tab[hdr_index].hdr = RT_NULL;
pin_irq_hdr_tab[hdr_index].mode = 0;
pin_irq_hdr_tab[hdr_index].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
/**
* @brief pin irq enable
* @param device, pin, enabled
* @retval None
*/
static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
{
const struct pin_index *index;
const struct pin_irq_map *irqmap;
rt_base_t level;
rt_int32_t hdr_index = -1;
exti_trig_type_enum trigger_mode;
index = get_pin(pin);
if (index == RT_NULL)
{
return -RT_EINVAL;
}
if (enabled == PIN_IRQ_ENABLE)
{
hdr_index = bit2bitno(index->pin);
if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
{
return -RT_EINVAL;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[hdr_index].pin == -1)
{
rt_hw_interrupt_enable(level);
return -RT_EINVAL;
}
irqmap = &pin_irq_map[hdr_index];
switch (pin_irq_hdr_tab[hdr_index].mode)
{
case PIN_IRQ_MODE_RISING:
trigger_mode = EXTI_TRIG_RISING;
break;
case PIN_IRQ_MODE_FALLING:
trigger_mode = EXTI_TRIG_FALLING;
break;
case PIN_IRQ_MODE_RISING_FALLING:
trigger_mode = EXTI_TRIG_BOTH;
break;
default:
rt_hw_interrupt_enable(level);
return -RT_EINVAL;
}
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx
rcu_periph_clock_enable(RCU_SYSCFG);
#elif defined SOC_SERIES_GD32E23x
rcu_periph_clock_enable(RCU_CFGCMP);
#else
rcu_periph_clock_enable(RCU_AF);
#endif
/* enable and set interrupt priority */
#if defined SOC_SERIES_GD32E23x
nvic_irq_enable(irqmap->irqno, 5U);
#else
nvic_irq_enable(irqmap->irqno, 5U, 0U);
#endif
/* connect EXTI line to GPIO pin */
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x
syscfg_exti_line_config(index->port_src, index->pin_src);
#else
gpio_exti_source_select(index->port_src, index->pin_src);
#endif
/* configure EXTI line */
exti_init((exti_line_enum)(index->exit_line), EXTI_INTERRUPT, trigger_mode);
exti_interrupt_flag_clear((exti_line_enum)(index->exit_line));
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
irqmap = get_pin_irq_map(index->pin);
if (irqmap == RT_NULL)
{
return -RT_EINVAL;
}
nvic_irq_disable(irqmap->irqno);
}
else
{
return -RT_EINVAL;
}
return RT_EOK;
}
const static struct rt_pin_ops gd32_pin_ops = {
.pin_mode = gd32_pin_mode,
.pin_write = gd32_pin_write,
.pin_read = gd32_pin_read,
.pin_attach_irq = gd32_pin_attach_irq,
.pin_detach_irq = gd32_pin_detach_irq,
.pin_irq_enable = gd32_pin_irq_enable,
RT_NULL,
};
/**
* @brief pin write
* @param irqno
* @retval None
*/
rt_inline void pin_irq_hdr(int irqno)
{
if (pin_irq_hdr_tab[irqno].hdr)
{
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
}
}
/**
* @brief gd32 exit interrupt
* @param exti_line
* @retval None
*/
void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line)
{
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
exti_line_enum pin_exti_line = exti_line;
#else
exti_line_enum pin_exti_line = 1 << exti_line;
#endif
if (RESET != exti_interrupt_flag_get(pin_exti_line))
{
pin_irq_hdr(exti_line);
exti_interrupt_flag_clear(pin_exti_line);
}
}
#if defined SOC_SERIES_GD32E23x
void EXTI0_1_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(0);
GD32_GPIO_EXTI_IRQHandler(1);
rt_interrupt_leave();
}
void EXTI2_3_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(2);
GD32_GPIO_EXTI_IRQHandler(3);
rt_interrupt_leave();
}
void EXTI4_15_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(4);
GD32_GPIO_EXTI_IRQHandler(5);
GD32_GPIO_EXTI_IRQHandler(6);
GD32_GPIO_EXTI_IRQHandler(7);
GD32_GPIO_EXTI_IRQHandler(8);
GD32_GPIO_EXTI_IRQHandler(9);
GD32_GPIO_EXTI_IRQHandler(10);
GD32_GPIO_EXTI_IRQHandler(11);
GD32_GPIO_EXTI_IRQHandler(12);
GD32_GPIO_EXTI_IRQHandler(13);
GD32_GPIO_EXTI_IRQHandler(14);
GD32_GPIO_EXTI_IRQHandler(15);
rt_interrupt_leave();
}
#else
void EXTI0_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(0);
rt_interrupt_leave();
}
void EXTI1_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(1);
rt_interrupt_leave();
}
void EXTI2_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(2);
rt_interrupt_leave();
}
void EXTI3_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(3);
rt_interrupt_leave();
}
void EXTI4_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(4);
rt_interrupt_leave();
}
void EXTI5_9_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(5);
GD32_GPIO_EXTI_IRQHandler(6);
GD32_GPIO_EXTI_IRQHandler(7);
GD32_GPIO_EXTI_IRQHandler(8);
GD32_GPIO_EXTI_IRQHandler(9);
rt_interrupt_leave();
}
void EXTI10_15_IRQHandler(void)
{
rt_interrupt_enter();
GD32_GPIO_EXTI_IRQHandler(10);
GD32_GPIO_EXTI_IRQHandler(11);
GD32_GPIO_EXTI_IRQHandler(12);
GD32_GPIO_EXTI_IRQHandler(13);
GD32_GPIO_EXTI_IRQHandler(14);
GD32_GPIO_EXTI_IRQHandler(15);
rt_interrupt_leave();
}
#endif
int rt_hw_pin_init(void)
{
int result;
result = rt_device_pin_register("pin", &gd32_pin_ops, RT_NULL);
return result;
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
#endif

278
828ECO/drivers/drv_hwtimer.c

@ -0,0 +1,278 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-25 iysheng first version
* 2025-10-22 kurisaw optimized configuration
*/
#include <board.h>
#include <rtdevice.h>
#include "drv_hwtimer.h"
#include "hwtimer_config.h"
#ifdef RT_USING_HWTIMER
/*
* static void __set_timerx_freq
* Set freq with timerx
*
* @param timerx the pointer of TIMER_TypeDef
* @param freq of the timer clock
* @retval None
*/
static void __set_timerx_freq(uint32_t timerx, uint32_t freq)
{
uint32_t ap1freq, ap2freq;
uint16_t prescaler;
uint32_t temp;
uint32_t timesel;
uint32_t APBPSC_limit;
uint32_t multiple;
timesel = RCU_CFG1 & RCU_CFG1_TIMERSEL;
if (timesel == 0)
{
multiple = 2;
APBPSC_limit = 0b100;
}
else
{
multiple = 4;
APBPSC_limit = 0b101;
}
/* APB1 */
if (!(timerx & (1 << 16)))
{
ap1freq = rcu_clock_freq_get(CK_APB1);
/* Check if APB1 is divided */
temp = RCU_CFG0 & RCU_CFG0_APB1PSC;
temp >>= (__builtin_ctz(temp));
/* When the division factor is less than expected, the clock frequency equals AHB clock, otherwise needs multiplication */
prescaler = (temp <= APBPSC_limit) ? (rcu_clock_freq_get(CK_AHB) / freq - 1) : ((ap1freq * multiple) / freq - 1);
}
else /* APB2 */
{
ap2freq = rcu_clock_freq_get(CK_APB2);
/* Check if APB2 is divided */
temp = RCU_CFG0 & RCU_CFG0_APB2PSC;
temp >>= (__builtin_ctz(temp));
/* When the division factor is less than expected, the clock frequency equals AHB clock, otherwise needs multiplication */
prescaler = (temp <= APBPSC_limit) ? (rcu_clock_freq_get(CK_AHB) / freq - 1) : ((ap2freq * multiple) / freq - 1);
}
timer_prescaler_config(timerx, prescaler, TIMER_PSC_RELOAD_NOW);
}
static void gd32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
{
uint32_t timer_base = (uint32_t)timer->parent.user_data;
timer_parameter_struct initpara;
if (state)
{
/* Set internal clock source */
timer_internal_clock_config(timer_base);
/* Initialize timer configuration */
timer_struct_para_init(&initpara);
/* Set maximum timer period */
initpara.period = timer->info->maxcnt;
/* Configure timer */
timer_init(timer_base, &initpara);
/* Set timer input frequency */
__set_timerx_freq(timer_base, timer->info->maxfreq);
}
}
static rt_err_t gd32_hwtimer_start(struct rt_hwtimer_device *timer,
rt_uint32_t cnt, rt_hwtimer_mode_t mode)
{
uint32_t timer_base = (uint32_t)timer->parent.user_data;
if (mode == HWTIMER_MODE_ONESHOT)
{
timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_SINGLE);
}
else if (mode == HWTIMER_MODE_PERIOD)
{
timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_REPETITIVE);
}
/* Reset timer count value */
timer_counter_value_config(timer_base, 0);
/* Set timer auto-reload value */
timer_autoreload_value_config(timer_base, cnt - 1);
/* Enable timer */
timer_enable(timer_base);
return 0;
}
static void gd32_hwtimer_stop(struct rt_hwtimer_device *timer)
{
uint32_t timer_base = (uint32_t)timer->parent.user_data;
timer_disable(timer_base);
}
static rt_uint32_t gd32_hwtimer_count_get(struct rt_hwtimer_device *timer)
{
uint32_t timer_base = (uint32_t)timer->parent.user_data;
rt_uint32_t count;
count = timer_counter_read(timer_base);
return count;
}
static rt_err_t gd32_hwtimer_control(struct rt_hwtimer_device *timer, rt_uint32_t cmd,
void *args)
{
int ret = RT_EOK;
rt_int32_t freq;
switch (cmd)
{
case HWTIMER_CTRL_FREQ_SET:
freq = *(rt_uint32_t *)args;
__set_timerx_freq((uint32_t)timer->parent.user_data, freq);
break;
default:
rt_kprintf("invalid cmd:%x\n", cmd);
ret = -RT_EINVAL;
break;
}
return ret;
}
static const struct rt_hwtimer_ops g_gd32_hwtimer_ops = {
gd32_hwtimer_init,
gd32_hwtimer_start,
gd32_hwtimer_stop,
gd32_hwtimer_count_get,
gd32_hwtimer_control,
};
static gd32_hwtimer_device g_gd32_hwtimer[] = {
#ifdef BSP_USING_HWTIMER0
HWTIMER0_CONFIG,
#endif
#ifdef BSP_USING_HWTIMER1
HWTIMER1_CONFIG,
#endif
#ifdef BSP_USING_HWTIMER2
HWTIMER2_CONFIG,
#endif
#ifdef BSP_USING_HWTIMER3
HWTIMER3_CONFIG,
#endif
#ifdef BSP_USING_HWTIMER4
HWTIMER4_CONFIG,
#endif
#ifdef BSP_USING_HWTIMER5
HWTIMER5_CONFIG,
#endif
#ifdef BSP_USING_HWTIMER6
HWTIMER6_CONFIG,
#endif
#ifdef BSP_USING_HWTIMER7
HWTIMER7_CONFIG,
#endif
};
#ifdef BSP_USING_HWTIMER0
void TIMER0_UP_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTIMER1
void TIMER1_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTIMER2
void TIMER2_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTIMER3
void TIMER3_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTIMER4
void TIMER4_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTIMER5
void TIMER5_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTIMER6
void TIMER6_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTIMER7
void TIMER7_UP_IRQHandler(void)
{
rt_interrupt_enter();
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev);
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP);
rt_interrupt_leave();
}
#endif
static int rt_hwtimer_init(void)
{
int ret = 0, i = 0;
for (; i < sizeof(g_gd32_hwtimer) / sizeof(g_gd32_hwtimer[0]); i++)
{
g_gd32_hwtimer[i].hwtimer_dev.ops = &g_gd32_hwtimer_ops;
g_gd32_hwtimer[i].hwtimer_dev.info = &g_gd32_hwtimer[i].hwtimer_info;
/* Enable clock */
rcu_periph_clock_enable(g_gd32_hwtimer[i].hw_data.rcu);
/* Set timer interrupt priority */
NVIC_SetPriority(g_gd32_hwtimer[i].hw_data.irqn, 0);
/* Enable NVIC */
NVIC_EnableIRQ(g_gd32_hwtimer[i].hw_data.irqn);
/* Enable timer interrupt */
timer_interrupt_enable(g_gd32_hwtimer[i].hw_data.reg_base, TIMER_INT_UP);
/* Register device to system */
ret = rt_device_hwtimer_register(&g_gd32_hwtimer[i].hwtimer_dev,
g_gd32_hwtimer[i].dev_name, (void *)g_gd32_hwtimer[i].hw_data.reg_base);
if (RT_EOK != ret)
{
rt_kprintf("failed register %s, err=%d\n", g_gd32_hwtimer[i].dev_name,
ret);
break;
}
}
return ret;
}
INIT_BOARD_EXPORT(rt_hwtimer_init);
#endif

622
828ECO/drivers/drv_i2c.c

@ -0,0 +1,622 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-12-20 BruceOu the first version
* 2025-10-10 WangShun compatible with RT-Studio
*/
#include "drv_i2c.h"
#include "i2c_config.h"
#ifdef RT_USING_I2C
#define DBG_TAG "drv.i2c"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && \
!defined(BSP_USING_I2C4) && !defined(BSP_USING_I2C5)
#error "Please define at least one BSP_USING_I2Cx"
/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
#endif
#if defined(BSP_USING_I2C0)
struct rt_i2c_bus_device i2c0;
#endif /* BSP_USING_I2C0 */
#if defined(BSP_USING_I2C1)
struct rt_i2c_bus_device i2c1;
#endif /* BSP_USING_I2C1 */
#if defined(BSP_USING_I2C2)
struct rt_i2c_bus_device i2c2;
#endif /* BSP_USING_I2C2 */
#if defined(BSP_USING_I2C3)
struct rt_i2c_bus_device i2c3;
#endif /* BSP_USING_I2C3 */
#if defined(BSP_USING_I2C4)
struct rt_i2c_bus_device i2c4;
#endif /* BSP_USING_I2C4 */
#if defined(BSP_USING_I2C5)
struct rt_i2c_bus_device i2c5;
#endif /* BSP_USING_I2C5 */
#if defined(SOC_SERIES_GD32F5xx)
#define i2c_flag_get_gd i2c_add_flag_get
#define i2c_timing_config_gd i2c_add_timing_config
#define i2c_master_clock_config_gd i2c_add_master_clock_config
#define i2c_enable_gd i2c_add_enable
#define i2c_flag_clear_gd i2c_add_flag_clear
#define i2c_stop_on_bus_gd i2c_add_stop_on_bus
#define i2c_transfer_byte_number_config_gd i2c_add_transfer_byte_number_config
#define i2c_start_on_bus_gd i2c_add_start_on_bus
#define i2c_address10_enable_gd i2c_add_address10_enable
#define i2c_address10_disable_gd i2c_add_address10_disable
#define i2c_master_addressing_gd i2c_add_master_addressing
#define i2c_data_transmit_gd i2c_add_data_transmit
#define i2c_data_receive_gd i2c_add_data_receive
#define I2C_FLAG_RBNE_GD I2C_ADD_FLAG_RBNE
#define I2C_STAT_GD I2C_ADD_STAT
#define I2C_STAT_TBE_GD I2C_ADD_STAT_TBE
#define I2C_STAT_TI_GD I2C_ADD_STAT_TI
#define I2C_MASTER_RECEIVE_GD I2C_ADD_MASTER_RECEIVE
#define I2C_MASTER_TRANSMIT_GD I2C_ADD_MASTER_TRANSMIT
#define I2C_FLAG_I2CBSY_GD I2C_ADD_FLAG_I2CBSY
#define I2C_FLAG_TC_GD I2C_ADD_FLAG_TC
#define I2C_FLAG_TI_GD I2C_ADD_FLAG_TI
#define I2C_FLAG_STPDET_GD I2C_ADD_FLAG_STPDET
#else
#define i2c_flag_get_gd i2c_flag_get
#define i2c_timing_config_gd i2c_timing_config
#define i2c_master_clock_config_gd i2c_master_clock_config
#define i2c_enable_gd i2c_enable
#define i2c_flag_clear_gd i2c_flag_clear
#define i2c_data_receive_gd i2c_data_receive
#define i2c_data_transmit_gd i2c_data_transmit
#define i2c_address10_enable_gd i2c_address10_enable
#define i2c_address10_disable_gd i2c_address10_disable
#define i2c_master_addressing_gd i2c_master_addressing
#define i2c_transfer_byte_number_config_gd i2c_transfer_byte_number_config
#define i2c_start_on_bus_gd i2c_start_on_bus
#define i2c_stop_on_bus_gd i2c_stop_on_bus
#if defined(SOC_SERIES_GD32E51x)
#undef i2c_flag_get_gd
#undef i2c_flag_clear_gd
#undef i2c_master_addressing_gd
#define i2c_flag_get_gd i2c2_flag_get
#define i2c_flag_clear_gd i2c2_flag_clear
#define i2c_master_addressing_gd i2c2_master_addressing
#undef I2C_STAT_GD
#undef I2C_STAT_TBE_GD
#undef I2C_STAT_TI_GD
#define I2C_STAT_GD I2C2_STAT
#define I2C_STAT_TBE_GD I2C2_STAT_TBE
#define I2C_STAT_TI_GD I2C2_STAT_TI
#undef I2C_MASTER_RECEIVE_GD
#undef I2C_MASTER_TRANSMIT_GD
#define I2C_MASTER_RECEIVE_GD I2C2_MASTER_RECEIVE
#define I2C_MASTER_TRANSMIT_GD I2C2_MASTER_TRANSMIT
#undef I2C_FLAG_RBNE_GD
#undef I2C_FLAG_I2CBSY_GD
#undef I2C_FLAG_TC_GD
#undef I2C_FLAG_TI_GD
#undef I2C_FLAG_STPDET_GD
#define I2C_FLAG_RBNE_GD I2C2_FLAG_RBNE
#define I2C_FLAG_I2CBSY_GD I2C2_FLAG_I2CBSY
#define I2C_FLAG_TC_GD I2C2_FLAG_TC
#define I2C_FLAG_TI_GD I2C2_FLAG_TI
#define I2C_FLAG_STPDET_GD I2C2_FLAG_STPDET
/* also needed in write path */
#define I2C_FLAG_TBE_GD I2C2_FLAG_TBE
#else
#define I2C_FLAG_RBNE_GD I2C_FLAG_RBNE
#define I2C_STAT_GD I2C_STAT
#define I2C_STAT_TBE_GD I2C_STAT_TBE
#define I2C_STAT_TI_GD I2C_STAT_TI
#define I2C_MASTER_RECEIVE_GD I2C_MASTER_RECEIVE
#define I2C_MASTER_TRANSMIT_GD I2C_MASTER_TRANSMIT
#define I2C_FLAG_I2CBSY_GD I2C_FLAG_I2CBSY
#define I2C_FLAG_TC_GD I2C_FLAG_TC
#define I2C_FLAG_TI_GD I2C_FLAG_TI
#define I2C_FLAG_STPDET_GD I2C_FLAG_STPDET
/* used in write path */
#define I2C_FLAG_TBE_GD I2C_FLAG_TBE
#endif
#endif
#if defined(SOC_SERIES_GD32F5xx)
#define IS_I2C_LEGACY(periph) ((periph) == I2C0 || (periph) == I2C1 || (periph) == I2C2)
#elif defined(SOC_SERIES_GD32F4xx)
#define IS_I2C_LEGACY(periph) (1)
#elif defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x)
#define IS_I2C_LEGACY(periph) (0)
#elif defined(SOC_SERIES_GD32E51x)
#define IS_I2C_LEGACY(periph) ((periph) == I2C0 || (periph) == I2C1)
#endif
static const struct gd32_i2c_bus gd_i2c_config[] = {
#ifdef BSP_USING_I2C0
I2C0_CONFIG,
#endif
#ifdef BSP_USING_I2C1
I2C1_CONFIG,
#endif
#ifdef BSP_USING_I2C2
I2C2_CONFIG,
#endif
#ifdef BSP_USING_I2C3
I2C3_CONFIG,
#endif
#ifdef BSP_USING_I2C4
I2C4_CONFIG,
#endif
#ifdef BSP_USING_I2C5
I2C5_CONFIG,
#endif
};
/**
* @brief This function initializes the i2c pin.
* @param i2c
* @retval None
*/
static void gd32_i2c_gpio_init(const struct gd32_i2c_bus *i2c)
{
rt_uint32_t scl_port, sda_port;
rt_uint32_t scl_pin, sda_pin;
rt_uint32_t pin_af;
rcu_periph_enum scl_periph, sda_periph;
if (get_pin_config(i2c->scl_pin_name, &scl_port, &scl_pin, &scl_periph) == -RT_ERROR)
{
return;
}
if (get_pin_config(i2c->sda_pin_name, &sda_port, &sda_pin, &sda_periph) == -RT_ERROR)
{
return;
}
pin_alternate_config(i2c->alternate, &pin_af);
/* enable I2C and GPIO clock */
rcu_periph_clock_enable(scl_periph);
rcu_periph_clock_enable(sda_periph);
rcu_periph_clock_enable(i2c->per_clk);
/* configure I2C_SCL as alternate function push-pull */
#if defined(SOC_SERIES_GD32E51x)
gpio_init(scl_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, scl_pin);
gpio_init(sda_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, sda_pin);
if (!IS_I2C_LEGACY(i2c->i2c_periph))
{
rcu_periph_clock_enable(RCU_AF);
gpio_afio_port_config(AFIO_PA8_I2C2_CFG, ENABLE);
gpio_afio_port_config(AFIO_PC9_I2C2_CFG, ENABLE);
}
else
{
i2c_deinit(i2c->i2c_periph);
}
/* configure remap function */
if (i2c->i2c_remap != 0)
{
rcu_periph_clock_enable(RCU_AF);
gpio_pin_remap_config(i2c->i2c_remap, ENABLE);
}
gpio_init(scl_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, scl_pin);
gpio_init(sda_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, sda_pin);
/* configure alternate1 function */
if (pin_af != 0 || pin_af != 0)
{
rcu_periph_clock_enable(RCU_AF);
gpio_afio_port_config(pin_af, ENABLE);
gpio_afio_port_config(pin_af, ENABLE);
}
i2c_deinit(i2c->i2c_periph);
#else
gpio_af_set(scl_port, pin_af, scl_pin);
gpio_mode_set(scl_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, scl_pin);
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
gpio_output_options_set(scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, scl_pin);
/* configure I2C_SDA as alternate function push-pull */
gpio_af_set(sda_port, pin_af, sda_pin);
gpio_mode_set(sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, sda_pin);
gpio_output_options_set(sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, sda_pin);
#else
gpio_output_options_set(scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, scl_pin);
/* configure I2C_SDA as alternate function push-pull */
gpio_af_set(sda_port, pin_af, sda_pin);
gpio_mode_set(sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, sda_pin);
gpio_output_options_set(sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, sda_pin);
#endif
#endif
}
/**
* @brief read data.
* @param i2c_periph
* @param *p_buffer
* @param data_byte
* @retval None
*/
static uint8_t gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint8_t *p_buffer, rt_uint16_t data_byte)
{
if (data_byte == 0)
return 1;
/* while there is data to be read */
while (data_byte)
{
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x)
if (IS_I2C_LEGACY(i2c_periph))
{
if (3 == data_byte)
{
/* wait until BTC bit is set */
while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC))
;
/* disable acknowledge */
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
}
if (2 == data_byte)
{
/* wait until BTC bit is set */
while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC))
;
/* send a stop condition to I2C bus */
i2c_stop_on_bus(i2c_periph);
}
/* wait until RBNE bit is set */
if (i2c_flag_get(i2c_periph, I2C_FLAG_RBNE))
{
/* read a byte from the EEPROM */
*p_buffer = i2c_data_receive(i2c_periph);
/* point to the next location where the byte read will be saved */
p_buffer++;
/* decrement the read bytes counter */
data_byte--;
}
}
else
#endif
{
/* wait until the RBNE bit is set */
while (!i2c_flag_get_gd(i2c_periph, I2C_FLAG_RBNE_GD))
;
/* read a byte */
*p_buffer = i2c_data_receive_gd(i2c_periph);
/* point to the next location where the byte read will be saved */
p_buffer++;
/* decrement the read bytes counter */
data_byte--;
}
}
return 0;
}
/**
* @brief write data.
* @param i2c_periph
* @param *p_buffer
* @param data_byte
* @retval None
*/
static uint8_t gd32_i2c_write(rt_uint32_t i2c_periph, uint8_t *p_buffer, uint16_t data_byte)
{
if (data_byte == 0)
return 1;
while (data_byte)
{
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x)
if (IS_I2C_LEGACY(i2c_periph))
{
/* data transmission */
i2c_data_transmit(i2c_periph, *p_buffer);
/* point to the next byte to be written */
p_buffer++;
/* decrement the write bytes counter */
data_byte--;
/* wait until the TI bit is set */
while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC))
;
}
else
#endif
{
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x)
/* wait until the transmit data buffer is empty */
I2C_STAT_GD(i2c_periph) |= I2C_STAT_TBE_GD;
while (!i2c_flag_get_gd(i2c_periph, I2C_FLAG_TBE))
;
while (data_byte)
{
/* wait until the TI bit is set */
while (!i2c_flag_get_gd(i2c_periph, I2C_FLAG_TI_GD))
;
/* data transmission */
i2c_data_transmit(i2c_periph, *p_buffer);
/* point to the next byte to be written */
p_buffer++;
/* decrement the write bytes counter */
data_byte--;
}
#endif
}
}
if (data_byte != 0)
{
return 1;
}
return 0;
}
static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
{
static struct rt_i2c_msg *msg;
rt_uint32_t i, w_total_byte = 0, r_total_byte = 0;
rt_err_t ret = RT_ERROR;
RT_ASSERT(bus != RT_NULL);
struct gd32_i2c_bus *gd32_i2c = (struct gd32_i2c_bus *)bus->priv;
for (i = 0; i < num; i++)
{
msg = &msgs[i];
if (msg->flags & RT_I2C_RD)
{
r_total_byte += msg->len;
}
else
{
w_total_byte += msg->len;
}
}
for (i = 0; i < num; i++)
{
msg = &msgs[i];
if (!(msg->flags & RT_I2C_NO_START))
{
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x)
if (IS_I2C_LEGACY(gd32_i2c->i2c_periph))
{
if (msg->flags & RT_I2C_RD)
{
if (i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY))
{
i2c_stop_on_bus(gd32_i2c->i2c_periph);
}
/* enable acknowledge */
i2c_ack_config(gd32_i2c->i2c_periph, I2C_ACK_ENABLE);
/* i2c master sends start signal only when the bus is idle */
while (i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY))
;
/* send the start signal */
i2c_start_on_bus(gd32_i2c->i2c_periph);
/* i2c master sends START signal successfully */
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND))
;
i2c_master_addressing(gd32_i2c->i2c_periph, msg->addr, I2C_RECEIVER);
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND))
;
/* address flag set means i2c slave sends ACK */
i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND);
}
else
{
/* configure slave address */
while (i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY))
;
//i2c_transfer_byte_number_config(gd32_i2c->i2c_periph, w_total_byte);
/* send a start condition to I2C bus */
i2c_start_on_bus(gd32_i2c->i2c_periph);
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND))
;
i2c_master_addressing(gd32_i2c->i2c_periph, msg->addr, I2C_TRANSMITTER);
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND))
;
i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND);
}
}
else
#endif
{
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x)
if (msg->flags & RT_I2C_ADDR_10BIT)
{
/* enable 10-bit addressing mode in master mode */
i2c_address10_enable_gd(gd32_i2c->i2c_periph);
}
else
{
/* disable 10-bit addressing mode in master mode */
i2c_address10_disable_gd(gd32_i2c->i2c_periph);
}
if (msg->flags & RT_I2C_RD)
{
/* configure slave address */
i2c_master_addressing_gd(gd32_i2c->i2c_periph, msg->addr, I2C_MASTER_RECEIVE_GD);
i2c_transfer_byte_number_config_gd(gd32_i2c->i2c_periph, r_total_byte);
/* send a start condition to I2C bus */
i2c_start_on_bus_gd(gd32_i2c->i2c_periph);
}
else
{
/* configure slave address */
i2c_master_addressing_gd(gd32_i2c->i2c_periph, msg->addr, I2C_MASTER_TRANSMIT_GD);
while (i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY_GD))
;
i2c_transfer_byte_number_config_gd(gd32_i2c->i2c_periph, w_total_byte);
/* send a start condition to I2C bus */
i2c_start_on_bus_gd(gd32_i2c->i2c_periph);
}
#endif
}
}
if (msg->flags & RT_I2C_RD)
{
if (gd32_i2c_read(gd32_i2c->i2c_periph, msg->buf, msg->len) != 0)
{
LOG_E("i2c bus read failed,i2c bus stop!");
goto out;
}
}
else
{
if (gd32_i2c_write(gd32_i2c->i2c_periph, msg->buf, msg->len) != 0)
{
LOG_E("i2c bus write failed,i2c bus stop!");
goto out;
}
}
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x)
if (!IS_I2C_LEGACY(gd32_i2c->i2c_periph))
{
if (r_total_byte != 0)
{
while (!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_TC_GD))
;
}
}
#endif
}
ret = i;
out:
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x)
if (IS_I2C_LEGACY(gd32_i2c->i2c_periph))
{
if (!(msg->flags & RT_I2C_NO_STOP))
{
if (msg->flags & RT_I2C_RD)
{
while ((I2C_CTL0(gd32_i2c->i2c_periph) & I2C_CTL0_STOP))
;
}
else
{
/* send a stop condition to I2C bus */
i2c_stop_on_bus(gd32_i2c->i2c_periph);
/* wait until stop condition generate */
while ((I2C_CTL0(gd32_i2c->i2c_periph) & I2C_CTL0_STOP))
;
/* clear the STPDET bit */
}
}
}
else
#endif
{
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x)
if (!(msg->flags & RT_I2C_NO_STOP))
{
while (!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_TC_GD))
;
/* send a stop condition to I2C bus */
i2c_stop_on_bus_gd(gd32_i2c->i2c_periph);
/* wait until stop condition generate */
while (!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_STPDET_GD))
;
/* clear the STPDET bit */
i2c_flag_clear_gd(gd32_i2c->i2c_periph, I2C_FLAG_STPDET_GD);
}
#endif
}
return ret;
}
static const struct rt_i2c_bus_device_ops i2c_ops = {
.master_xfer = gd32_i2c_master_xfer,
.slave_xfer = RT_NULL,
.i2c_bus_control = RT_NULL
};
/**
* @brief I2C initialization function
* @param None
* @retval RT_EOK indicates successful initialization.
*/
int rt_hw_i2c_init(void)
{
rt_size_t obj_num = sizeof(gd_i2c_config) / sizeof(gd_i2c_config[0]);
for (int i = 0; i < obj_num; i++)
{
gd32_i2c_gpio_init(&gd_i2c_config[i]);
/* configure I2C timing. I2C speed clock=400kHz*/
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x)
if (IS_I2C_LEGACY(gd_i2c_config[i].i2c_periph))
{
i2c_clock_config(gd_i2c_config[i].i2c_periph, 100000, I2C_DTCY_2);
i2c_mode_addr_config(gd_i2c_config[i].i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xa0);
i2c_enable(gd_i2c_config[i].i2c_periph);
i2c_ack_config(gd_i2c_config[i].i2c_periph, I2C_ACK_ENABLE);
}
else
#endif
{
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x)
i2c_timing_config_gd(gd_i2c_config[i].i2c_periph, 0x1, 0x7, 0);
i2c_master_clock_config_gd(gd_i2c_config[i].i2c_periph, 0x2D, 0x87);
/* enable I2C1 */
i2c_enable_gd(gd_i2c_config[i].i2c_periph);
#endif
}
gd_i2c_config[i].i2c_bus->ops = &i2c_ops;
gd_i2c_config[i].i2c_bus->priv = (void *)&gd_i2c_config[i];
rt_i2c_bus_device_register(gd_i2c_config[i].i2c_bus, gd_i2c_config[i].device_name);
}
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_i2c_init);
#endif /* RT_USING_I2C */

403
828ECO/drivers/drv_lcd.c

@ -0,0 +1,403 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include <stddef.h>
#include <rthw.h>
#include <rtthread.h>
#include "drv_lcd.h"
#ifdef RT_USING_LCD
#define DBG_TAG "drv_lcd"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
struct drv_lcd_device
{
struct rt_device parent;
struct rt_device_graphic_info lcd_info;
};
static uint16_t *frame_buffer = RT_NULL;
struct drv_lcd_device _lcd = { 0 };
RGB color_write = { 0, 0xFF, 0xFF, 0xFF };
RGB color_black = { 0, 0x00, 0x00, 0x00 };
RGB color_red = { 0, 0xFF, 0x00, 0x00 };
RGB color_blue = { 0, 0x00, 0x00, 0xFF };
RGB color_green = { 0, 0x00, 0xFF, 0x00 };
RGB color_yellow = { 0, 0xFF, 0xFF, 0x00 };
RGB color_cyan = { 0, 0x00, 0xFF, 0xFF };
RGB color_magenta = { 0, 0xFF, 0x00, 0xFF };
RGB color_orange = { 0, 0xFF, 0xA5, 0x00 };
RGB color_purple = { 0, 0x80, 0x00, 0x80 };
RGB color_gray = { 0, 0x80, 0x80, 0x80 };
RGB color_lightgray = { 0, 0xD3, 0xD3, 0xD3 };
RGB color_darkgray = { 0, 0x40, 0x40, 0x40 };
RGB color_brown = { 0, 0xA5, 0x2A, 0x2A };
RGB color_pink = { 0, 0xFF, 0xC0, 0xCB };
RGB color_gold = { 0, 0xFF, 0xD7, 0x00 };
RGB color_silver = { 0, 0xC0, 0xC0, 0xC0 };
static void framebuffer_init(void);
static void tli_config(RGB *blackground_color);
static void tli_gpio_config(void);
rt_err_t drv_lcd_init(rt_device_t dev)
{
return RT_EOK;
}
rt_err_t drv_lcd_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
rt_err_t drv_lcd_close(rt_device_t dev)
{
return RT_EOK;
}
rt_ssize_t drv_lcd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
return RT_EOK;
}
rt_ssize_t drv_lcd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
return RT_EOK;
}
rt_err_t drv_lcd_control(struct rt_device *device, int cmd, void *args)
{
switch (cmd)
{
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
RT_ASSERT(info != RT_NULL);
info->pixel_format = _lcd.lcd_info.pixel_format;
info->bits_per_pixel = _lcd.lcd_info.bits_per_pixel;
info->width = _lcd.lcd_info.width;
info->height = _lcd.lcd_info.height;
info->framebuffer = _lcd.lcd_info.framebuffer;
}
break;
case RTGRAPHIC_CTRL_RECT_UPDATE:
tli_reload_config(TLI_REQUEST_RELOAD_EN);
break;
default:
return RT_EOK;
}
return RT_EOK;
}
static int hw_drv_lcd_init(void)
{
// malloc frame buffer
frame_buffer = rt_malloc(ACTIVE_WIDTH * ACTIVE_HEIGHT * PRE_PIXEL_BYTES);
framebuffer_init();
_lcd.parent.type = RT_Device_Class_Graphic;
_lcd.parent.init = drv_lcd_init;
_lcd.parent.open = drv_lcd_open;
_lcd.parent.close = drv_lcd_close;
_lcd.parent.read = drv_lcd_read;
_lcd.parent.write = drv_lcd_write;
_lcd.parent.control = drv_lcd_control;
_lcd.lcd_info.framebuffer = (rt_uint8_t *)frame_buffer;
_lcd.lcd_info.width = LCD_WIGHT;
_lcd.lcd_info.height = LCD_HIGHT;
_lcd.lcd_info.bits_per_pixel = PRE_PIXEL_BYTES * 8;
_lcd.lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
/* configure TLI peripheral */
tli_config(&color_write);
/* enable TLI layers */
tli_layer_enable(LAYER0);
tli_reload_config(TLI_REQUEST_RELOAD_EN);
/* enable TLI */
tli_enable();
rt_device_register(&_lcd.parent, "lcd", RT_DEVICE_FLAG_RDWR);
return RT_EOK;
}
INIT_APP_EXPORT(hw_drv_lcd_init);
static void framebuffer_init(void)
{
for (uint32_t y = 0; y < ACTIVE_HEIGHT; ++y)
{
for (uint32_t x = 0; x < ACTIVE_WIDTH; ++x)
{
frame_buffer[y * ACTIVE_WIDTH + x] = 0xFFFF;
}
}
SCB_CleanInvalidateDCache();
}
static void tli_gpio_config(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_GPIOF);
rcu_periph_clock_enable(RCU_GPIOH);
rcu_periph_clock_enable(RCU_GPIOG);
/* configure HSYNC(PE15), VSYNC(PA7), PCLK(PG7) */
gpio_af_set(GPIOE, GPIO_AF_10, GPIO_PIN_15);
gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_7);
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_7);
gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_15);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7);
/* configure LCD_R7(PG6), LCD_R6(PH12), LCD_R5(PH11), LCD_R4(PA5), LCD_R3(PH9),LCD_R2(PH8),
LCD_R1(PH3), LCD_R0(PH2) */
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_6);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_12);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_11);
gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_5);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_9);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_8);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_3);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_2);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_6);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_12);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_11);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_5);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_9);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_3);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_2);
/* configure LCD_G7(PD3), LCD_G6(PC7), LCD_G5(PC1), LCD_G4(PH15), LCD_G3(PH14), LCD_G2(PH13),LCD_G1(PB0), LCD_G0(PB1) */
gpio_af_set(GPIOD, GPIO_AF_14, GPIO_PIN_3);
gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_7);
gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_1);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_15);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_14);
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_13);
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_0);
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_1);
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_3);
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7);
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_1);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_15);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_14);
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_13);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_0);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_1);
/* configure LCD_B7(PB9), LCD_B6(PB8), LCD_B5(PB5), LCD_B4(PC11), LCD_B3(PG11),LCD_B2(PG10), LCD_B1(PG12), LCD_B0(PG14) */
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_9);
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_8);
gpio_af_set(GPIOB, GPIO_AF_3, GPIO_PIN_5);
gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_11);
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_11);
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_10);
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_12);
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_14);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_9);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_5);
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_11);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_11);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_10);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_12);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_14);
/* configure LCD_DE(PF10) */
gpio_af_set(GPIOF, GPIO_AF_14, GPIO_PIN_10);
gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_10);
/* LCD PWM BackLight(PG13) */
gpio_mode_set(GPIOG, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_13);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_13);
gpio_bit_set(GPIOG, GPIO_PIN_13);
}
static void tli_config(RGB *blackground_color)
{
tli_parameter_struct tli_init_struct;
tli_layer_parameter_struct tli_layer_init_struct;
rcu_periph_clock_enable(RCU_TLI);
tli_gpio_config();
rcu_pll_input_output_clock_range_config(IDX_PLL2, RCU_PLL2RNG_1M_2M, RCU_PLL2VCO_192M_836M);
if (ERROR == rcu_pll2_config(25, 192, 3, 3, 3))
{
while (1)
{
}
}
rcu_pll_clock_output_enable(RCU_PLL2R);
rcu_tli_clock_div_config(RCU_PLL2R_DIV8);
rcu_osci_on(RCU_PLL2_CK);
if (ERROR == rcu_osci_stab_wait(RCU_PLL2_CK))
{
while (1)
{
}
}
/* configure TLI parameter struct */
tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW;
tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW;
tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW;
tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI;
/* LCD display timing configuration */
tli_init_struct.synpsz_hpsz = HORIZONTAL_SYNCHRONOUS_PULSE - 1;
tli_init_struct.synpsz_vpsz = VERTICAL_SYNCHRONOUS_PULSE - 1;
tli_init_struct.backpsz_hbpsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1;
tli_init_struct.backpsz_vbpsz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH - 1;
tli_init_struct.activesz_hasz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH - 1;
tli_init_struct.activesz_vasz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT -
1;
tli_init_struct.totalsz_htsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH +
HORIZONTAL_FRONT_PORCH - 1;
tli_init_struct.totalsz_vtsz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT +
VERTICAL_FRONT_PORCH - 1;
/* configure LCD background R,G,B values */
tli_init_struct.backcolor_red = blackground_color->R;
tli_init_struct.backcolor_green = blackground_color->G;
tli_init_struct.backcolor_blue = blackground_color->B;
tli_init(&tli_init_struct);
/* TLI layer configuration */
tli_layer_init_struct.layer_window_leftpos = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH;
tli_layer_init_struct.layer_window_rightpos = (480 + HORIZONTAL_SYNCHRONOUS_PULSE +
HORIZONTAL_BACK_PORCH - 1);
tli_layer_init_struct.layer_window_toppos = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH;
tli_layer_init_struct.layer_window_bottompos = (272 + VERTICAL_SYNCHRONOUS_PULSE +
VERTICAL_BACK_PORCH - 1);
tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565;
tli_layer_init_struct.layer_sa = 255;
tli_layer_init_struct.layer_default_blue = 0x0;
tli_layer_init_struct.layer_default_green = 0x0;
tli_layer_init_struct.layer_default_red = 0x0;
tli_layer_init_struct.layer_default_alpha = 0x00;
tli_layer_init_struct.layer_acf1 = LAYER_ACF1_SA;
tli_layer_init_struct.layer_acf2 = LAYER_ACF2_SA;
tli_layer_init_struct.layer_frame_bufaddr = (uint32_t)frame_buffer;
tli_layer_init_struct.layer_frame_line_length = ((480 * 2) + 7);
tli_layer_init_struct.layer_frame_buf_stride_offset = (480 * 2);
tli_layer_init_struct.layer_frame_total_line_number = 272;
tli_layer_init(LAYER0, &tli_layer_init_struct);
}
void lcd_draw_picture(uint32_t picture_addr, uint32_t picture_width, uint32_t picture_height, uint32_t picture_x, uint32_t picture_y)
{
ipa_destination_parameter_struct ipa_destination_init_struct;
ipa_foreground_parameter_struct ipa_fg_init_struct;
uint16_t *_address = &frame_buffer[picture_y * ACTIVE_WIDTH + picture_x];
uint32_t line_offset = ACTIVE_WIDTH - picture_width;
rcu_periph_clock_enable(RCU_IPA);
ipa_deinit();
/* configure IPA pixel format convert mode */
ipa_pixel_format_convert_mode_set(IPA_FGTODE);
/* configure destination pixel format */
ipa_destination_init_struct.destination_pf = IPA_DPF_RGB565;
/* configure destination memory base address */
ipa_destination_init_struct.destination_memaddr = (uint32_t)_address;
/* configure destination pre-defined alpha value RGB */
ipa_destination_init_struct.destination_pregreen = 0;
ipa_destination_init_struct.destination_preblue = 0;
ipa_destination_init_struct.destination_prered = 0;
ipa_destination_init_struct.destination_prealpha = 0;
/* configure destination line offset */
ipa_destination_init_struct.destination_lineoff = line_offset;
/* configure height of the image to be processed */
ipa_destination_init_struct.image_height = picture_height;
/* configure width of the image to be processed */
ipa_destination_init_struct.image_width = picture_width;
ipa_destination_init_struct.image_rotate = DESTINATION_ROTATE_0;
ipa_destination_init_struct.image_hor_decimation = DESTINATION_HORDECIMATE_DISABLE;
ipa_destination_init_struct.image_ver_decimation = DESTINATION_VERDECIMATE_DISABLE;
/* IPA destination initialization */
ipa_destination_init(&ipa_destination_init_struct);
/* configure IPA foreground */
ipa_fg_init_struct.foreground_memaddr = picture_addr;
ipa_fg_init_struct.foreground_pf = FOREGROUND_PPF_RGB565;
ipa_fg_init_struct.foreground_alpha_algorithm = IPA_FG_ALPHA_MODE_0;
ipa_fg_init_struct.foreground_prealpha = 0x0;
ipa_fg_init_struct.foreground_lineoff = 0x0;
ipa_fg_init_struct.foreground_preblue = 0x0;
ipa_fg_init_struct.foreground_pregreen = 0x0;
ipa_fg_init_struct.foreground_prered = 0x0;
/* foreground initialization */
ipa_foreground_init(&ipa_fg_init_struct);
/* start transfer */
ipa_transfer_enable();
while (RESET == ipa_interrupt_flag_get(IPA_INT_FLAG_FTF))
{
}
}
void lcd_draw_point(uint32_t point_x, uint32_t point_y, RGB *color)
{
frame_buffer[point_y * ACTIVE_WIDTH + point_x] = to_RGB565(color);
}
uint32_t to_RGB565(RGB *color)
{
uint32_t res = ((uint32_t)(color->R & 0xF8) << 8) | ((uint32_t)(color->G & 0xFC) << 3) | ((uint32_t)(color->B & 0xF8) >> 3);
return res;
}
#endif /* RT_USING_LCD */

296
828ECO/drivers/drv_pwm.c

@ -0,0 +1,296 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-06-05 zengjianwei first version
* 2025-06-23 Yucai Liu Support for non-complementary PWM output with advanced timers
* 2025-10-11 kurisaw compatible with RT-Studio
*/
#include "drv_pwm.h"
#include "pwm_config.h"
#ifdef RT_USING_PWM
#define DBG_TAG "drv.pwm"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#define MAX_PERIOD 65535
#define MIN_PERIOD 3
#define MIN_PULSE 2
static struct gd32_pwm gd32_pwm_obj[] = {
#ifdef BSP_USING_PWM0
PWM0_CONFIG,
#endif
#ifdef BSP_USING_PWM1
PWM1_CONFIG,
#endif
#ifdef BSP_USING_PWM2
PWM2_CONFIG,
#endif
#ifdef BSP_USING_PWM3
PWM3_CONFIG,
#endif
#ifdef BSP_USING_PWM4
PWM4_CONFIG,
#endif
#ifdef BSP_USING_PWM5
PWM5_CONFIG,
#endif
#ifdef BSP_USING_PWM6
PWM6_CONFIG,
#endif
#ifdef BSP_USING_PWM7
PWM7_CONFIG,
#endif
};
typedef struct
{
rt_uint32_t timer_periph;
rt_bool_t initialized;
} TIMER_INIT_STATUS;
static TIMER_INIT_STATUS timer_init_status[] = {
{ TIMER0, RT_FALSE },
{ TIMER1, RT_FALSE },
{ TIMER2, RT_FALSE },
{ TIMER3, RT_FALSE },
{ TIMER4, RT_FALSE },
{ TIMER5, RT_FALSE },
{ TIMER6, RT_FALSE },
{ TIMER7, RT_FALSE },
};
static void gd32_pwm_init(struct gd32_pwm *gd32_pwm)
{
rt_uint32_t pwm_port, pwm_pin;
rcu_periph_enum pwm_periph;
rt_uint32_t pin_af;
if (get_pin_config(gd32_pwm->pin_name, &pwm_port, &pwm_pin, &pwm_periph) == -RT_ERROR)
{
return;
}
pin_alternate_config(gd32_pwm->alternate, &pin_af);
/* enable timer clock */
rcu_periph_clock_enable(gd32_pwm->timer_clk);
rcu_periph_clock_enable(pwm_periph);
/* GPIO pin configuration */
gpio_af_set(pwm_port, pin_af, pwm_pin);
gpio_mode_set(pwm_port, GPIO_MODE_AF, GPIO_PUPD_NONE, pwm_pin);
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
gpio_output_options_set(pwm_port, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, pwm_pin);
#else
gpio_output_options_set(pwm_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pwm_pin);
#endif
}
static rt_err_t drv_pwm_enable(struct gd32_pwm *pwm_dev, struct rt_pwm_configuration *configuration, rt_bool_t enable)
{
if (!enable)
{
timer_channel_output_state_config(pwm_dev->timer_periph, configuration->channel, TIMER_CCX_DISABLE);
}
else
{
if (configuration->complementary == RT_TRUE)
{
timer_channel_output_state_config(pwm_dev->timer_periph, configuration->channel - 1, TIMER_CCXN_ENABLE);
}
else
{
timer_channel_output_state_config(pwm_dev->timer_periph, configuration->channel, TIMER_CCX_ENABLE);
}
}
return RT_EOK;
}
static rt_err_t drv_pwm_get(struct gd32_pwm *pwm_dev, struct rt_pwm_configuration *configuration)
{
rt_uint64_t tim_clock;
rt_uint16_t psc;
rt_uint32_t chxcv;
tim_clock = rcu_clock_freq_get(CK_SYS);
psc = timer_prescaler_read(pwm_dev->timer_periph);
if (psc == TIMER_CKDIV_DIV2)
{
tim_clock = tim_clock / 2;
}
else if (psc == TIMER_CKDIV_DIV4)
{
tim_clock = tim_clock / 4;
}
chxcv = timer_channel_capture_value_register_read(pwm_dev->timer_periph, configuration->channel);
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
tim_clock /= 1000000UL;
configuration->period = (TIMER_CAR(pwm_dev->timer_periph) + 1) * (psc + 1) * 1000UL / tim_clock;
configuration->pulse = (chxcv + 1) * (psc + 1) * 1000UL / tim_clock;
return RT_EOK;
}
static rt_err_t drv_pwm_set(struct gd32_pwm *pwm_dev, struct rt_pwm_configuration *configuration)
{
rt_uint32_t period, pulse;
rt_uint64_t tim_clock, psc;
tim_clock = rcu_clock_freq_get(CK_SYS);
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
tim_clock /= 1000000UL;
period = (unsigned long long)configuration->period * tim_clock / 1000ULL;
psc = period / MAX_PERIOD + 1;
period = period / psc;
timer_prescaler_config(pwm_dev->timer_periph, psc - 1, TIMER_PSC_RELOAD_NOW);
if (period < MIN_PERIOD)
{
period = MIN_PERIOD;
}
timer_autoreload_value_config(pwm_dev->timer_periph, period - 1);
pulse = (unsigned long long)configuration->pulse * tim_clock / psc / 1000ULL;
if (pulse < MIN_PULSE)
{
pulse = MIN_PULSE;
}
else if (pulse > period)
{
pulse = period;
}
timer_channel_output_pulse_value_config(pwm_dev->timer_periph, configuration->channel, pulse);
timer_counter_value_config(pwm_dev->timer_periph, 0);
/* Update frequency value */
timer_event_software_generate(pwm_dev->timer_periph, TIMER_EVENT_SRC_UPG);
return RT_EOK;
}
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
{
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
struct gd32_pwm *pwm_dev = (struct gd32_pwm *)device;
switch (cmd)
{
case PWM_CMD_ENABLE:
return drv_pwm_enable(pwm_dev, configuration, RT_TRUE);
case PWM_CMD_DISABLE:
return drv_pwm_enable(pwm_dev, configuration, RT_FALSE);
case PWM_CMD_SET:
return drv_pwm_set(pwm_dev, configuration);
case PWM_CMD_GET:
return drv_pwm_get(pwm_dev, configuration);
default:
return -RT_EINVAL;
}
}
static struct rt_pwm_ops drv_ops = {
.control = drv_pwm_control
};
static void timer_initialize(uint32_t timer_periph)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
/* Check if timer is already initialized */
for (int i = 0; i < sizeof(timer_init_status) / sizeof(timer_init_status[0]); i++)
{
if (timer_init_status[i].timer_periph == timer_periph && !timer_init_status[i].initialized)
{
/* TIMER configuration */
timer_initpara.prescaler = 119;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 15999;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(timer_periph, &timer_initpara);
/* CHX configuration in PWM mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(gd32_pwm_obj[i].timer_periph, gd32_pwm_obj[i].channel, &timer_ocintpara);
timer_init_status[i].initialized = RT_TRUE;
/* Configure channel output */
timer_channel_output_pulse_value_config(gd32_pwm_obj[i].timer_periph,
gd32_pwm_obj[i].channel, 7999);
timer_channel_output_mode_config(gd32_pwm_obj[i].timer_periph,
gd32_pwm_obj[i].channel, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(gd32_pwm_obj[i].timer_periph,
gd32_pwm_obj[i].channel, TIMER_OC_SHADOW_DISABLE);
/* Enable timer */
timer_primary_output_config(timer_periph, ENABLE);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(gd32_pwm_obj[i].timer_periph);
timer_enable(timer_periph);
break;
}
}
}
static int drv_pwm_init(void)
{
int i, result = RT_EOK;
for (i = 0; i < sizeof(gd32_pwm_obj) / sizeof(gd32_pwm_obj[0]); i++)
{
/* Initialize PWM hardware */
gd32_pwm_init(&gd32_pwm_obj[i]);
/* Initialize timer if not already initialized */
timer_initialize(gd32_pwm_obj[i].timer_periph);
/* Register PWM device */
if (rt_device_pwm_register(&gd32_pwm_obj[i].pwm_device, gd32_pwm_obj[i].name,
&drv_ops, RT_NULL) == RT_EOK)
{
LOG_D("%s register success", gd32_pwm_obj[i].name);
}
else
{
LOG_E("%s register failed", gd32_pwm_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_DEVICE_EXPORT(drv_pwm_init);
#endif /* RT_USING_PWM */

443
828ECO/drivers/drv_rtc.c

@ -0,0 +1,443 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-01-25 iysheng first version
* 2025-09-25 kurisaw adapt to rt_rtc_ops interface
* 2025-09-25 kurisaw add alarm interrupt support
*/
#include <board.h>
#include <rtdevice.h>
#include <rthw.h>
#include <sys/time.h>
#define DBG_TAG "drv.rtc"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#ifdef RT_USING_RTC
#if defined(RT_USING_ALARM)
#if defined(BSP_USING_ALARM0) && defined(BSP_USING_ALARM1)
#error "Only supports using one alarm at a time."
#elif !defined(BSP_USING_ALARM0) && !defined(BSP_USING_ALARM1)
#error "Please Enable RTC alarm define (BSP_USING_ALARM0 | BSP_USING_ALARM1)"
#elif defined(BSP_USING_ALARM0)
#define BSP_ALARM_FLAG RTC_FLAG_ALARM0
#define BSP_RTC_ALARM RTC_ALARM0
#define BSP_RTC_INT_ALARM RTC_INT_ALARM0
#elif defined(BSP_USING_ALARM1)
#define BSP_ALARM_FLAG RTC_FLAG_ALARM1
#define BSP_RTC_ALARM RTC_ALARM1
#define BSP_RTC_INT_ALARM RTC_INT_ALARM1
#endif
#endif
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
#define rtc_year year
#define rtc_month month
#define rtc_date date
#define rtc_day_of_week day_of_week
#define rtc_hour hour
#define rtc_minute minute
#define rtc_second second
#define rtc_display_format display_format
#endif
static time_t get_rtc_timestamp(void);
static rt_err_t set_rtc_timestamp(time_t time_stamp);
/**
* @brief Helper function: Convert BCD value to binary.
* @param val: BCD value.
* @return Binary value.
*/
static rt_uint8_t bcd_to_bin(rt_uint8_t val)
{
return (val & 0x0F) + ((val >> 4) & 0x0F) * 10;
}
/**
* @brief Helper function: Convert binary to BCD.
* @param val: Binary value.
* @return BCD value.
*/
static rt_uint8_t bin_to_bcd(rt_uint8_t val)
{
return ((val / 10) << 4) | (val % 10);
}
#ifdef RT_USING_ALARM
/* RTC device for alarm callback */
static rt_device_t g_rtc_device = RT_NULL;
/**
* @brief RTC Alarm Interrupt Handler
*/
void RTC_Alarm_IRQHandler(void)
{
rt_interrupt_enter();
/* Check if alarm interrupt occurred */
if (rtc_flag_get(RTC_FLAG_ALARM0) != RESET)
{
/* Clear alarm flag */
rtc_flag_clear(RTC_FLAG_ALARM0);
exti_flag_clear(EXTI_17);
/* Notify RTC framework about alarm event */
if (g_rtc_device != RT_NULL)
{
rt_alarm_update(g_rtc_device, 1);
}
LOG_D("RTC Alarm0 triggered");
}
if (rtc_flag_get(RTC_FLAG_ALARM1) != RESET)
{
/* Clear alarm flag */
rtc_flag_clear(RTC_FLAG_ALARM1);
exti_flag_clear(EXTI_17);
/* Notify RTC framework about alarm event */
if (g_rtc_device != RT_NULL)
{
rt_alarm_update(g_rtc_device, 1);
}
LOG_D("RTC Alarm1 triggered");
}
rt_interrupt_leave();
}
#endif /* RT_USING_ALARM */
static rt_err_t gd_rtc_init(void)
{
/* Enable PMU and backup domain clocks */
rcu_periph_clock_enable(RCU_PMU);
pmu_backup_write_enable();
/* Enable BKP and RTC clocks */
#ifdef SOC_SERIES_GD32F10x
rcu_periph_clock_enable(RCU_BKPI);
#else
rcu_periph_clock_enable(RCU_RTC);
#endif
/* Check if RTC is already initialized by backup domain reset */
if (RTC_STAT & RTC_STAT_INITF)
{
LOG_D("RTC already initialized");
return RT_EOK;
}
/* Reset backup domain only if RTC is not running */
if ((RTC_STAT & RTC_STAT_RSYNF) == 0)
{
rcu_bkp_reset_enable();
rcu_bkp_reset_disable();
/* Re-enable clocks after reset */
#ifdef SOC_SERIES_GD32F10x
rcu_periph_clock_enable(RCU_BKPI);
#else
rcu_periph_clock_enable(RCU_RTC);
#endif
}
/* Use LSE (32.768kHz) as RTC clock source */
#define PRESCALER_S 0xFF
#define PRESCALER_A 0x7F
rcu_osci_on(RCU_LXTAL);
if (rcu_osci_stab_wait(RCU_LXTAL) != SUCCESS)
{
LOG_E("LSE oscillator failed to stabilize");
return -RT_ERROR;
}
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
LOG_D("RTC clock source: LSE (32.768kHz)");
/* Wait for RTC registers synchronization */
if (rtc_register_sync_wait() != SUCCESS)
{
LOG_E("RTC register synchronization failed");
return -RT_ERROR;
}
/* Set default time if RTC is not initialized */
if ((RTC_DATE == 0) || (RTC_TIME == 0))
{
time_t default_time = 1704067200; /* 2024-01-01 00:00:00 */
if (set_rtc_timestamp(default_time) != RT_EOK)
{
LOG_E("Failed to set default RTC time");
return -RT_ERROR;
}
LOG_D("RTC set to default time: 2024-01-01 00:00:00");
}
LOG_D("RTC initialization successful");
return RT_EOK;
}
static time_t get_rtc_timestamp(void)
{
struct tm tm_new = {0};
rtc_parameter_struct rtc_current_time;
/* Wait for register synchronization before reading */
if (rtc_register_sync_wait() != SUCCESS)
{
LOG_E("RTC sync failed before reading time");
return 0;
}
rtc_current_time_get(&rtc_current_time);
/* Convert BCD to binary and adjust year/month values */
tm_new.tm_year = bcd_to_bin(rtc_current_time.rtc_year) + 100; /* RTC year starts from 2000 */
tm_new.tm_mon = bcd_to_bin(rtc_current_time.rtc_month) - 1; /* tm_mon: 0-11 */
tm_new.tm_mday = bcd_to_bin(rtc_current_time.rtc_date);
tm_new.tm_hour = bcd_to_bin(rtc_current_time.rtc_hour);
tm_new.tm_min = bcd_to_bin(rtc_current_time.rtc_minute);
tm_new.tm_sec = bcd_to_bin(rtc_current_time.rtc_second);
/* Convert weekday: RTC uses 1-7 (Monday-Sunday), tm uses 0-6 (Sunday-Saturday) */
uint8_t rtc_wday = bcd_to_bin(rtc_current_time.rtc_day_of_week);
tm_new.tm_wday = (rtc_wday == 7) ? 0 : rtc_wday; /* Sunday conversion */
/* Calculate day of year */
tm_new.tm_yday = 0; /* Will be calculated by timegm */
tm_new.tm_isdst = 0; /* No daylight saving */
/* Use timegm instead of mktime to avoid timezone issues */
return timegm(&tm_new);
}
static rt_err_t gd_get_secs(time_t *sec)
{
if (sec == RT_NULL)
{
return -RT_EINVAL;
}
*sec = get_rtc_timestamp();
LOG_D("RTC: get timestamp %lu", *sec);
return RT_EOK;
}
static rt_err_t set_rtc_timestamp(time_t time_stamp)
{
struct tm now;
rtc_parameter_struct rtc_init_struct;
ErrStatus status;
/* Use gmtime_r for thread safety */
gmtime_r(&time_stamp, &now);
if (now.tm_year < 100)
{
LOG_E("Year must be >= 2000");
return -RT_ERROR;
}
/* Convert to BCD format */
rtc_init_struct.rtc_year = bin_to_bcd(now.tm_year - 100); /* RTC year: 0-99 (2000-2099) */
rtc_init_struct.rtc_month = bin_to_bcd(now.tm_mon + 1); /* RTC month: 1-12 */
rtc_init_struct.rtc_date = bin_to_bcd(now.tm_mday);
/* Convert weekday: tm_wday 0-6 (Sun-Sat) to RTC 1-7 (Mon-Sun) */
rtc_init_struct.rtc_day_of_week = bin_to_bcd(now.tm_wday == 0 ? 7 : now.tm_wday);
rtc_init_struct.rtc_hour = bin_to_bcd(now.tm_hour);
rtc_init_struct.rtc_minute = bin_to_bcd(now.tm_min);
rtc_init_struct.rtc_second = bin_to_bcd(now.tm_sec);
rtc_init_struct.rtc_display_format = RTC_24HOUR;
/* Use default prescaler values */
rtc_init_struct.factor_asyn = PRESCALER_A;
rtc_init_struct.factor_syn = PRESCALER_S;
rtc_init_struct.am_pm = RTC_AM;
status = rtc_init(&rtc_init_struct);
if (status != SUCCESS)
{
LOG_E("RTC time set failed: %d", status);
return -RT_ERROR;
}
/* Wait for synchronization after setting time */
if (rtc_register_sync_wait() != SUCCESS)
{
LOG_E("RTC sync failed after setting time");
return -RT_ERROR;
}
LOG_D("RTC time set successfully: %lu", time_stamp);
return RT_EOK;
}
static rt_err_t gd_set_secs(time_t *sec)
{
if (sec == RT_NULL)
{
return -RT_EINVAL;
}
rt_err_t result = set_rtc_timestamp(*sec);
if (result == RT_EOK)
{
LOG_D("RTC: set rtc_time %lu", *sec);
}
else
{
LOG_E("RTC: set rtc_time failed %lu", *sec);
}
return result;
}
#ifdef RT_USING_ALARM
static rt_err_t gd_get_alarm(struct rt_rtc_wkalarm *alarm)
{
if (alarm == RT_NULL)
{
return -RT_EINVAL;
}
rtc_alarm_struct rtc_alarm;
/* Get current alarm configuration */
rtc_alarm_get(BSP_RTC_ALARM, &rtc_alarm);
/* Convert RTC alarm to RT-Thread alarm format */
alarm->tm_hour = bcd_to_bin(rtc_alarm.alarm_hour);
alarm->tm_min = bcd_to_bin(rtc_alarm.alarm_minute);
alarm->tm_sec = bcd_to_bin(rtc_alarm.alarm_second);
/* Check if alarm is enabled */
alarm->enable = (RTC_CTL & (BSP_RTC_ALARM == RTC_ALARM0 ? RTC_CTL_ALRM0EN : RTC_CTL_ALRM1EN)) ? 1 : 0;
LOG_D("RTC: get alarm %02d:%02d:%02d, enable: %d",
alarm->tm_hour, alarm->tm_min, alarm->tm_sec, alarm->enable);
return RT_EOK;
}
static rt_err_t gd_set_alarm(struct rt_rtc_wkalarm *alarm)
{
if (alarm == RT_NULL)
{
return -RT_EINVAL;
}
rtc_alarm_struct rtc_alarm;
rtc_alarm_disable(BSP_RTC_ALARM);
/* Initialize alarm structure */
rtc_alarm.alarm_mask = RTC_ALARM_ALL_MASK;
rtc_alarm.weekday_or_date = RTC_ALARM_DATE_SELECTED;
rtc_alarm.alarm_day = 1; /* Not used when mask is set to ALL_MASK */
rtc_alarm.alarm_hour = bin_to_bcd(alarm->tm_hour);
rtc_alarm.alarm_minute = bin_to_bcd(alarm->tm_min);
rtc_alarm.alarm_second = bin_to_bcd(alarm->tm_sec);
rtc_alarm.am_pm = RTC_AM;
/* Configure alarm */
rtc_alarm_config(BSP_RTC_ALARM, &rtc_alarm);
/* Enable or disable alarm */
if (alarm->enable)
{
/* Clear any pending alarm flag first */
rtc_flag_clear(BSP_ALARM_FLAG);
/* Clear EXTI line 17 flag */
exti_flag_clear(EXTI_17);
/* Enable RTC alarm interrupt */
rtc_interrupt_enable(BSP_RTC_INT_ALARM);
/* Enable alarm */
rtc_alarm_enable(BSP_RTC_ALARM);
/* Configure EXTI line 17 for RTC alarm interrupt */
exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
/* Enable RTC Alarm global interrupt in NVIC */
nvic_irq_enable(RTC_Alarm_IRQn, 0, 0);
LOG_D("RTC Alarm enabled with interrupt");
}
else
{
/* Disable alarm interrupt first */
rtc_interrupt_disable(BSP_RTC_INT_ALARM);
/* Disable alarm */
rtc_alarm_disable(BSP_RTC_ALARM);
/* Clear alarm flag */
rtc_flag_clear(BSP_ALARM_FLAG);
exti_flag_clear(EXTI_17);
LOG_D("RTC Alarm disabled");
}
LOG_D("RTC: set alarm %02d:%02d:%02d, enable: %d",
alarm->tm_hour, alarm->tm_min, alarm->tm_sec, alarm->enable);
return RT_EOK;
}
#endif /* RT_USING_ALARM */
static const struct rt_rtc_ops gd_rtc_ops =
{
.init = gd_rtc_init,
.get_secs = gd_get_secs,
.set_secs = gd_set_secs,
#ifdef RT_USING_ALARM
.set_alarm = gd_set_alarm,
.get_alarm = gd_get_alarm,
#endif
};
static rt_rtc_dev_t gd_rtc_dev;
static int rt_hw_rtc_init(void)
{
rt_err_t result;
gd_rtc_dev.ops = &gd_rtc_ops;
result = rt_hw_rtc_register(&gd_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
if (result != RT_EOK)
{
LOG_E("RTC register failed: %d", result);
return result;
}
#ifdef RT_USING_ALARM
/* Store RTC device for alarm callback */
g_rtc_device = rt_device_find("rtc");
if (g_rtc_device == RT_NULL)
{
LOG_W("RTC device not found for alarm callback");
}
#endif
LOG_D("RTC hardware init success");
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
#endif /* RT_USING_RTC */

3278
828ECO/drivers/drv_sdio.c

File diff suppressed because it is too large

640
828ECO/drivers/drv_spi.c

@ -0,0 +1,640 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-12-20 BruceOu first implementation
* 2025-10-10 WangShun compatible with RT-Studio
*/
#include "drv_spi.h"
#include "spi_config.h"
#ifdef RT_USING_SPI
#if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5)
#define DBG_TAG "drv.spi"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef BSP_USING_SPI0
static struct rt_spi_bus spi_bus0;
#endif
#ifdef BSP_USING_SPI1
static struct rt_spi_bus spi_bus1;
#endif
#ifdef BSP_USING_SPI2
static struct rt_spi_bus spi_bus2;
#endif
#ifdef BSP_USING_SPI3
static struct rt_spi_bus spi_bus3;
#endif
#ifdef BSP_USING_SPI4
static struct rt_spi_bus spi_bus4;
#endif
#ifdef BSP_USING_SPI5
static struct rt_spi_bus spi_bus5;
#endif
#ifdef RT_SPI_USING_DMA
gd32_spi_dma spi_dma[] = {
{
DMA0,
DMA_CH2,
DMA_CH3,
DMA_REQUEST_SPI0_TX,
DMA_REQUEST_SPI0_RX,
DMA_INTF_FTFIF,
0
},
{
DMA0,
DMA_CH2,
DMA_CH3,
DMA_REQUEST_SPI1_TX,
DMA_REQUEST_SPI1_RX,
DMA_INTF_FTFIF,
0
},
{
DMA0,
DMA_CH2,
DMA_CH3,
DMA_REQUEST_SPI2_TX,
DMA_REQUEST_SPI2_RX,
DMA_INTF_FTFIF,
0
},
{
DMA0,
DMA_CH2,
DMA_CH3,
DMA_REQUEST_SPI3_TX,
DMA_REQUEST_SPI3_RX,
DMA_INTF_FTFIF,
0
},
{
DMA0,
DMA_CH2,
DMA_CH3,
DMA_REQUEST_SPI4_TX,
DMA_REQUEST_SPI4_RX,
DMA_INTF_FTFIF,
0
},
{
DMA0,
DMA_CH2,
DMA_CH3,
DMA_REQUEST_SPI5_TX,
DMA_REQUEST_SPI5_RX,
DMA_INTF_FTFIF,
0
},
};
#endif
static const struct gd32_spi spi_bus_obj[] = {
#ifdef BSP_USING_SPI0
SPI0_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI1
SPI1_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI2
SPI2_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI3
SPI3_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI4
SPI4_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI5
SPI5_BUS_CONFIG,
#endif
};
/* private rt-thread spi ops function */
static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration);
static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message);
static struct rt_spi_ops gd32_spi_ops = {
.configure = spi_configure,
.xfer = spixfer,
};
/**
* @brief SPI Initialization
* @param gd32_spi: SPI BUS
* @retval None
*/
static void gd32_spi_init(struct gd32_spi *gd32_spi)
{
rt_uint32_t sck_port, miso_port, mosi_port;
rt_uint32_t sck_pin, miso_pin, mosi_pin;
rcu_periph_enum sck_periph, miso_periph, mosi_periph;
rt_uint32_t pin_af;
if (get_pin_config(gd32_spi->sck_pin_name, &sck_port, &sck_pin, &sck_periph) == -RT_ERROR)
{
return;
}
if (get_pin_config(gd32_spi->miso_pin_name, &miso_port, &miso_pin, &miso_periph) == -RT_ERROR)
{
return;
}
if (get_pin_config(gd32_spi->mosi_pin_name, &mosi_port, &mosi_pin, &mosi_periph) == -RT_ERROR)
{
return;
}
pin_alternate_config(gd32_spi->alternate, &pin_af);
/* enable SPI clock */
rcu_periph_clock_enable(gd32_spi->spi_clk);
rcu_periph_clock_enable(sck_periph);
rcu_periph_clock_enable(miso_periph);
rcu_periph_clock_enable(mosi_periph);
/*GPIO pin configuration*/
gpio_af_set(sck_port, pin_af, sck_pin);
gpio_af_set(miso_port, pin_af, miso_pin);
gpio_af_set(mosi_port, pin_af, mosi_pin);
gpio_mode_set(sck_port, GPIO_MODE_AF, GPIO_PUPD_NONE, sck_pin);
gpio_mode_set(miso_port, GPIO_MODE_AF, GPIO_PUPD_NONE, miso_pin);
gpio_mode_set(mosi_port, GPIO_MODE_AF, GPIO_PUPD_NONE, mosi_pin);
gpio_output_options_set(sck_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, sck_pin);
gpio_output_options_set(miso_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, miso_pin);
gpio_output_options_set(mosi_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, mosi_pin);
}
static rt_err_t spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *configuration)
{
struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)device->bus;
struct gd32_spi *spi_device = (struct gd32_spi *)spi_bus->parent.user_data;
spi_parameter_struct spi_init_struct;
uint32_t spi_periph = spi_device->spi_periph;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL);
/* Init SPI */
gd32_spi_init(spi_device);
#if defined SOC_SERIES_GD32H7xx || defined(SOC_SERIES_GD32H75E)
/* data_width */
if (configuration->data_width >= 4 && configuration->data_width <= 32)
{
spi_init_struct.data_size = CFG0_DZ(configuration->data_width - 1);
}
else
{
return -RT_EIO;
}
#else
/* data_width */
if (configuration->data_width <= 8)
{
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
}
else if (configuration->data_width <= 16)
{
spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT;
}
else
{
return -RT_EIO;
}
#endif
/* baudrate */
{
rcu_clock_freq_enum spi_src;
uint32_t spi_apb_clock;
uint32_t max_hz;
max_hz = configuration->max_hz;
LOG_D("sys freq: %d\n", rcu_clock_freq_get(CK_SYS));
LOG_D("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2));
LOG_D("max freq: %d\n", max_hz);
#if defined SOC_SERIES_GD32E23x
spi_src = CK_APB2;
#else
if (spi_periph == SPI1 || spi_periph == SPI2)
{
spi_src = CK_APB1;
}
else
{
spi_src = CK_APB2;
}
#endif
spi_apb_clock = rcu_clock_freq_get(spi_src);
if (max_hz >= spi_apb_clock / 2)
{
spi_init_struct.prescale = SPI_PSC_2;
}
else if (max_hz >= spi_apb_clock / 4)
{
spi_init_struct.prescale = SPI_PSC_4;
}
else if (max_hz >= spi_apb_clock / 8)
{
spi_init_struct.prescale = SPI_PSC_8;
}
else if (max_hz >= spi_apb_clock / 16)
{
spi_init_struct.prescale = SPI_PSC_16;
}
else if (max_hz >= spi_apb_clock / 32)
{
spi_init_struct.prescale = SPI_PSC_32;
}
else if (max_hz >= spi_apb_clock / 64)
{
spi_init_struct.prescale = SPI_PSC_64;
}
else if (max_hz >= spi_apb_clock / 128)
{
spi_init_struct.prescale = SPI_PSC_128;
}
else
{
/* min prescaler 256 */
spi_init_struct.prescale = SPI_PSC_256;
}
} /* baudrate */
switch (configuration->mode & RT_SPI_MODE_3)
{
case RT_SPI_MODE_0:
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
break;
case RT_SPI_MODE_1:
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
break;
case RT_SPI_MODE_2:
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
break;
case RT_SPI_MODE_3:
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
break;
}
/* MSB or LSB */
if (configuration->mode & RT_SPI_MSB)
{
spi_init_struct.endian = SPI_ENDIAN_MSB;
}
else
{
spi_init_struct.endian = SPI_ENDIAN_LSB;
}
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_crc_off(spi_periph);
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
/* enable SPI byte access */
spi_byte_access_enable(spi_periph);
/* enable SPI NSS output */
spi_nss_output_enable(spi_periph);
#endif
/* init SPI */
spi_init(spi_periph, &spi_init_struct);
/* Enable SPI_MASTER */
spi_enable(spi_periph);
return RT_EOK;
}
#ifdef RT_SPI_USING_DMA
static rt_err_t dma_spi_config(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)device->bus;
struct gd32_spi *spi_device = (struct gd32_spi *)spi_bus->parent.user_data;
rt_uint8_t *recv_ptr_dma = RT_NULL;
rt_uint8_t *send_ptr_dma = RT_NULL;
dma_single_data_parameter_struct dma_init_struct;
/* deinitialize DMA registers of a channel */
dma_deinit(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch);
dma_deinit(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch);
dma_single_data_para_struct_init(&dma_init_struct);
/* SPI transmit DMA config */
dma_init_struct.request = spi_device->spi_dma->dma_mux_req_tx;
dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
if (message->send_buf == RT_NULL)
{
dma_init_struct.memory0_addr = (uint32_t)send_ptr_dma;
}
else
{
dma_init_struct.memory0_addr = (uint32_t)message->send_buf;
}
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
dma_init_struct.number = message->length;
dma_init_struct.periph_addr = (uint32_t)&SPI_TDATA(spi_device->spi_periph);
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
dma_single_data_mode_init(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, &dma_init_struct);
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, DMA_FLAG_FTF);
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, DMA_FLAG_HTF);
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, DMA_FLAG_FEE);
/* SPI receive DMA config */
dma_init_struct.request = spi_device->spi_dma->dma_mux_req_rx;
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
if (message->recv_buf == RT_NULL)
{
dma_init_struct.memory0_addr = (uint32_t)recv_ptr_dma;
}
else
{
dma_init_struct.memory0_addr = (uint32_t)message->recv_buf;
}
dma_init_struct.periph_addr = (uint32_t)&SPI_RDATA(spi_device->spi_periph);
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_single_data_mode_init(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, &dma_init_struct);
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, DMA_FLAG_FTF);
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, DMA_FLAG_HTF);
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, DMA_FLAG_FEE);
return RT_EOK;
}
#endif
static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct rt_spi_bus *gd32_spi_bus = (struct rt_spi_bus *)device->bus;
struct gd32_spi *spi_device = (struct gd32_spi *)gd32_spi_bus->parent.user_data;
struct rt_spi_configuration *config = &device->config;
uint32_t spi_periph = spi_device->spi_periph;
RT_ASSERT(device != NULL);
RT_ASSERT(message != NULL);
#ifdef RT_SPI_USING_DMA
dma_spi_config(device, message);
#endif
/* take CS */
if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
{
if (device->config.mode & RT_SPI_CS_HIGH)
{
rt_pin_write(device->cs_pin, PIN_HIGH);
}
else
{
rt_pin_write(device->cs_pin, PIN_LOW);
}
}
LOG_D("%s transfer prepare and start", spi_device->bus_name);
LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
spi_device->bus_name,
(uint32_t)message->send_buf,
(uint32_t)message->recv_buf, message->length);
{
if (config->data_width <= 8)
{
const rt_uint8_t *send_ptr = message->send_buf;
rt_uint8_t *recv_ptr = message->recv_buf;
rt_uint32_t size = message->length;
LOG_D("spi poll transfer start: %d\n", size);
while (size--)
{
rt_uint8_t data = 0xFF;
if (send_ptr != RT_NULL)
{
data = *send_ptr++;
}
/* Todo: replace register read/write by gd32f4 lib */
/* Wait until the transmit buffer is empty */
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
spi_master_transfer_start(spi_periph, SPI_TRANS_START);
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP))
;
#else
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE))
;
#endif
/* Send the byte */
spi_i2s_data_transmit(spi_periph, data);
/* Wait until a data is received */
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP))
;
#else
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE))
;
#endif
/* Get the received data */
data = spi_i2s_data_receive(spi_periph);
if (recv_ptr != RT_NULL)
{
*recv_ptr++ = data;
}
}
LOG_D("spi poll transfer finsh\n");
}
else if (config->data_width <= 16)
{
const rt_uint16_t *send_ptr = message->send_buf;
rt_uint16_t *recv_ptr = message->recv_buf;
rt_uint32_t size = message->length;
while (size--)
{
rt_uint16_t data = 0xFF;
if (send_ptr != RT_NULL)
{
data = *send_ptr++;
}
/* Wait until the transmit buffer is empty */
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
spi_master_transfer_start(spi_periph, SPI_TRANS_START);
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP))
;
#else
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE))
;
#endif
/* Send the byte */
spi_i2s_data_transmit(spi_periph, data);
/* Wait until a data is received */
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP))
;
#else
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE))
;
#endif
/* Get the received data */
data = spi_i2s_data_receive(spi_periph);
if (recv_ptr != RT_NULL)
{
*recv_ptr++ = data;
}
}
}
#if defined SOC_SERIES_GD32H7xx || defined(SOC_SERIES_GD32H75E)
else if (config->data_width <= 32)
{
const rt_uint32_t *send_ptr = message->send_buf;
rt_uint32_t *recv_ptr = message->recv_buf;
rt_uint32_t size = message->length;
/* SPI master start transfer */
spi_master_transfer_start(spi_periph, SPI_TRANS_START);
while (size--)
{
rt_uint32_t data = 0xFF;
if (send_ptr != RT_NULL)
{
data = *send_ptr++;
}
/* Wait until the transmit buffer is empty */
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP))
;
/* Send the byte */
spi_i2s_data_transmit(spi_periph, data);
/* Wait until a data is received */
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP))
;
/* Get the received data */
data = spi_i2s_data_receive(spi_periph);
if (recv_ptr != RT_NULL)
{
*recv_ptr++ = data;
}
}
}
#endif
else
{
return -RT_EIO;
}
}
/* release CS */
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
{
if (device->config.mode & RT_SPI_CS_HIGH)
rt_pin_write(device->cs_pin, PIN_LOW);
else
rt_pin_write(device->cs_pin, PIN_HIGH);
}
return message->length;
};
/**
* Attach the spi device to SPI bus, this function must be used after initialization.
*/
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t result;
struct rt_spi_device *spi_device;
/* attach the device to spi bus*/
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
if (cs_pin != PIN_NONE)
{
/* initialize the cs pin && select the slave*/
rt_pin_mode(cs_pin, PIN_MODE_OUTPUT);
rt_pin_write(cs_pin, PIN_HIGH);
}
result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
if (result != RT_EOK)
{
LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
}
RT_ASSERT(result == RT_EOK);
LOG_D("%s attach to %s done", device_name, bus_name);
return result;
}
int rt_hw_spi_init(void)
{
int result = 0;
int i;
for (i = 0; i < sizeof(spi_bus_obj) / sizeof(spi_bus_obj[0]); i++)
{
spi_bus_obj[i].spi_bus->parent.user_data = (void *)&spi_bus_obj[i];
result = rt_spi_bus_register(spi_bus_obj[i].spi_bus, spi_bus_obj[i].bus_name, &gd32_spi_ops);
RT_ASSERT(result == RT_EOK);
LOG_D("%s bus init done", spi_bus_obj[i].bus_name);
}
return result;
}
INIT_BOARD_EXPORT(rt_hw_spi_init);
#endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4 || BSP_USING_SPI5 */
#endif /* RT_USING_SPI */

1165
828ECO/drivers/drv_usart.c

File diff suppressed because it is too large

149
828ECO/drivers/drv_wdt.c

@ -0,0 +1,149 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-01-25 iysheng first version
* 2025-10-09 kurisaw fix inaccurate WDT clock timeout feeding issue
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#include <board.h>
#define DBG_TAG "drv.wdt"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_WDT
/* User-configurable macros for WDT clock source and prescaler */
/* Default select oscillator type: RCU_IRC32K */
#define WDT_OSCI_TYPE RCU_IRC32K
/* Prescaler divider value (must match WDT_PSC_VALUE) */
#define WDT_PSC_DIVIDER 256U
/* Prescaler register value */
#define WDT_PSC_VALUE FWDGT_PSC_DIV256
/* Derived values */
#define WDT_CLOCK_FREQ IRC32K_VALUE
#define WDT_TICK_HZ (WDT_CLOCK_FREQ / WDT_PSC_DIVIDER)
#define WDT_MAX_RELOAD_VALUE 0xfffU
typedef struct
{
struct rt_watchdog_device wdt;
rt_uint32_t min_threshold_s;
rt_uint32_t max_threshold_s;
rt_uint32_t current_threshold_s;
} gd32_wdt_device_t;
static gd32_wdt_device_t g_wdt_dev;
static rt_err_t gd32_wdt_init(rt_watchdog_t *wdt)
{
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
/* Enable and wait for oscillator stabilization */
rcu_osci_on(WDT_OSCI_TYPE);
if (ERROR == rcu_osci_stab_wait(WDT_OSCI_TYPE))
{
LOG_E("failed init %u clock for free watchdog.", WDT_OSCI_TYPE);
return -RT_EINVAL;
}
#endif
/* Calculate thresholds */
g_wdt_dev.min_threshold_s = 1U;
g_wdt_dev.max_threshold_s = ((WDT_MAX_RELOAD_VALUE + 1U) * WDT_PSC_DIVIDER) / WDT_CLOCK_FREQ;
LOG_I("WDT clock: %u Hz (tick: %u Hz), threshold section [%u, %u]",
WDT_CLOCK_FREQ, WDT_TICK_HZ,
g_wdt_dev.min_threshold_s, g_wdt_dev.max_threshold_s);
/* Configure FWDGT with max timeout */
fwdgt_write_enable();
if (fwdgt_config(WDT_MAX_RELOAD_VALUE, WDT_PSC_VALUE) != SUCCESS)
{
LOG_E("failed to configure FWDGT");
return -RT_ERROR;
}
fwdgt_enable();
return RT_EOK;
}
static rt_err_t gd32_wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
{
rt_uint32_t param;
switch (cmd)
{
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
fwdgt_counter_reload();
break;
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
param = *(rt_uint32_t *)arg;
if ((param > g_wdt_dev.max_threshold_s) ||
(param < g_wdt_dev.min_threshold_s))
{
LOG_E("invalid param@%u (out of [%u, %u])", param,
g_wdt_dev.min_threshold_s, g_wdt_dev.max_threshold_s);
return -RT_EINVAL;
}
else
{
g_wdt_dev.current_threshold_s = param;
rt_uint32_t reload_value = (param * WDT_TICK_HZ) - 1U;
fwdgt_write_enable();
if (fwdgt_config(reload_value, WDT_PSC_VALUE) != SUCCESS)
{
LOG_E("failed to set timeout %u s", param);
return -RT_ERROR;
}
fwdgt_write_disable();
}
break;
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
*(rt_uint32_t *)arg = g_wdt_dev.current_threshold_s;
break;
case RT_DEVICE_CTRL_WDT_START:
fwdgt_enable();
break;
default:
LOG_W("This command is not supported.");
return -RT_ERROR;
}
return RT_EOK;
}
static struct rt_watchdog_ops g_wdt_ops = {
gd32_wdt_init,
gd32_wdt_control,
};
static int rt_hw_wdt_init(void)
{
rt_err_t ret = RT_EOK;
g_wdt_dev.wdt.ops = &g_wdt_ops;
/* register watchdog device */
if (rt_hw_watchdog_register(&g_wdt_dev.wdt, "wdt",
RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
{
LOG_E("wdt device register failed.");
ret = -RT_ERROR;
}
else
{
LOG_D("wdt device register success.");
}
return ret;
}
INIT_PREV_EXPORT(rt_hw_wdt_init);
#endif

438
828ECO/drivers/include/config/adc_config.h

@ -0,0 +1,438 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-15 LZerro compatible with RT-Studio
* 2025-10-22 kurisaw optimize multi-channel GPIO configuration
*/
#ifndef __ADC_CONFIG_H__
#define __ADC_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include "drv_adc.h"
#ifdef RT_USING_ADC
#define MAX_EXTERN_ADC_CHANNEL 20
#endif
#ifdef BSP_USING_ADC0
#ifdef BSP_ADC0_CH0_PIN
#define ADC0_CH0_PIN BSP_ADC0_CH0_PIN
#else
#define ADC0_CH0_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH1_PIN
#define ADC0_CH1_PIN BSP_ADC0_CH1_PIN
#else
#define ADC0_CH1_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH2_PIN
#define ADC0_CH2_PIN BSP_ADC0_CH2_PIN
#else
#define ADC0_CH2_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH3_PIN
#define ADC0_CH3_PIN BSP_ADC0_CH3_PIN
#else
#define ADC0_CH3_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH4_PIN
#define ADC0_CH4_PIN BSP_ADC0_CH4_PIN
#else
#define ADC0_CH4_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH5_PIN
#define ADC0_CH5_PIN BSP_ADC0_CH5_PIN
#else
#define ADC0_CH5_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH6_PIN
#define ADC0_CH6_PIN BSP_ADC0_CH6_PIN
#else
#define ADC0_CH6_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH7_PIN
#define ADC0_CH7_PIN BSP_ADC0_CH7_PIN
#else
#define ADC0_CH7_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH8_PIN
#define ADC0_CH8_PIN BSP_ADC0_CH8_PIN
#else
#define ADC0_CH8_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH9_PIN
#define ADC0_CH9_PIN BSP_ADC0_CH9_PIN
#else
#define ADC0_CH9_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH10_PIN
#define ADC0_CH10_PIN BSP_ADC0_CH10_PIN
#else
#define ADC0_CH10_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH11_PIN
#define ADC0_CH11_PIN BSP_ADC0_CH11_PIN
#else
#define ADC0_CH11_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH12_PIN
#define ADC0_CH12_PIN BSP_ADC0_CH12_PIN
#else
#define ADC0_CH12_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH13_PIN
#define ADC0_CH13_PIN BSP_ADC0_CH13_PIN
#else
#define ADC0_CH13_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH14_PIN
#define ADC0_CH14_PIN BSP_ADC0_CH14_PIN
#else
#define ADC0_CH14_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH15_PIN
#define ADC0_CH15_PIN BSP_ADC0_CH15_PIN
#else
#define ADC0_CH15_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH16_PIN
#define ADC0_CH16_PIN BSP_ADC0_CH16_PIN
#else
#define ADC0_CH16_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH17_PIN
#define ADC0_CH17_PIN BSP_ADC0_CH17_PIN
#else
#define ADC0_CH17_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH18_PIN
#define ADC0_CH18_PIN BSP_ADC0_CH18_PIN
#else
#define ADC0_CH18_PIN RT_NULL
#endif
#ifdef BSP_ADC0_CH19_PIN
#define ADC0_CH19_PIN BSP_ADC0_CH19_PIN
#else
#define ADC0_CH19_PIN RT_NULL
#endif
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
ADC0, \
RCU_ADC0, \
{ \
ADC0_CH0_PIN, \
ADC0_CH1_PIN, \
ADC0_CH2_PIN, \
ADC0_CH3_PIN, \
ADC0_CH4_PIN, \
ADC0_CH5_PIN, \
ADC0_CH6_PIN, \
ADC0_CH7_PIN, \
ADC0_CH8_PIN, \
ADC0_CH9_PIN, \
ADC0_CH10_PIN, \
ADC0_CH11_PIN, \
ADC0_CH12_PIN, \
ADC0_CH13_PIN, \
ADC0_CH14_PIN, \
ADC0_CH15_PIN, \
ADC0_CH16_PIN, \
ADC0_CH17_PIN, \
ADC0_CH18_PIN, \
ADC0_CH19_PIN, \
}, \
&adc0, \
"adc0", \
}
#endif /* ADC0_CONFIG */
#endif /* BSP_USING_ADC0 */
#ifdef BSP_USING_ADC1
#ifdef BSP_ADC1_CH0_PIN
#define ADC1_CH0_PIN BSP_ADC1_CH0_PIN
#else
#define ADC1_CH0_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH1_PIN
#define ADC1_CH1_PIN BSP_ADC1_CH1_PIN
#else
#define ADC1_CH1_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH2_PIN
#define ADC1_CH2_PIN BSP_ADC1_CH2_PIN
#else
#define ADC1_CH2_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH3_PIN
#define ADC1_CH3_PIN BSP_ADC1_CH3_PIN
#else
#define ADC1_CH3_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH4_PIN
#define ADC1_CH4_PIN BSP_ADC1_CH4_PIN
#else
#define ADC1_CH4_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH5_PIN
#define ADC1_CH5_PIN BSP_ADC1_CH5_PIN
#else
#define ADC1_CH5_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH6_PIN
#define ADC1_CH6_PIN BSP_ADC1_CH6_PIN
#else
#define ADC1_CH6_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH7_PIN
#define ADC1_CH7_PIN BSP_ADC1_CH7_PIN
#else
#define ADC1_CH7_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH8_PIN
#define ADC1_CH8_PIN BSP_ADC1_CH8_PIN
#else
#define ADC1_CH8_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH9_PIN
#define ADC1_CH9_PIN BSP_ADC1_CH9_PIN
#else
#define ADC1_CH9_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH10_PIN
#define ADC1_CH10_PIN BSP_ADC1_CH10_PIN
#else
#define ADC1_CH10_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH11_PIN
#define ADC1_CH11_PIN BSP_ADC1_CH11_PIN
#else
#define ADC1_CH11_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH12_PIN
#define ADC1_CH12_PIN BSP_ADC1_CH12_PIN
#else
#define ADC1_CH12_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH13_PIN
#define ADC1_CH13_PIN BSP_ADC1_CH13_PIN
#else
#define ADC1_CH13_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH14_PIN
#define ADC1_CH14_PIN BSP_ADC1_CH14_PIN
#else
#define ADC1_CH14_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH15_PIN
#define ADC1_CH15_PIN BSP_ADC1_CH15_PIN
#else
#define ADC1_CH15_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH16_PIN
#define ADC1_CH16_PIN BSP_ADC1_CH16_PIN
#else
#define ADC1_CH16_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH17_PIN
#define ADC1_CH17_PIN BSP_ADC1_CH17_PIN
#else
#define ADC1_CH17_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH18_PIN
#define ADC1_CH18_PIN BSP_ADC1_CH18_PIN
#else
#define ADC1_CH18_PIN RT_NULL
#endif
#ifdef BSP_ADC1_CH19_PIN
#define ADC1_CH19_PIN BSP_ADC1_CH19_PIN
#else
#define ADC1_CH19_PIN RT_NULL
#endif
#ifndef ADC1_CONFIG
#define ADC1_CONFIG \
{ \
ADC1, \
RCU_ADC1, \
{ \
ADC1_CH0_PIN, \
ADC1_CH1_PIN, \
ADC1_CH2_PIN, \
ADC1_CH3_PIN, \
ADC1_CH4_PIN, \
ADC1_CH5_PIN, \
ADC1_CH6_PIN, \
ADC1_CH7_PIN, \
ADC1_CH8_PIN, \
ADC1_CH9_PIN, \
ADC1_CH10_PIN, \
ADC1_CH11_PIN, \
ADC1_CH12_PIN, \
ADC1_CH13_PIN, \
ADC1_CH14_PIN, \
ADC1_CH15_PIN, \
ADC1_CH16_PIN, \
ADC1_CH17_PIN, \
ADC1_CH18_PIN, \
ADC1_CH19_PIN, \
}, \
&adc1, \
"adc1", \
}
#endif /* ADC1_CONFIG */
#endif /* BSP_USING_ADC1 */
#ifdef BSP_USING_ADC2
#ifdef BSP_ADC2_CH0_PIN
#define ADC2_CH0_PIN BSP_ADC2_CH0_PIN
#else
#define ADC2_CH0_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH1_PIN
#define ADC2_CH1_PIN BSP_ADC2_CH1_PIN
#else
#define ADC2_CH1_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH2_PIN
#define ADC2_CH2_PIN BSP_ADC2_CH2_PIN
#else
#define ADC2_CH2_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH3_PIN
#define ADC2_CH3_PIN BSP_ADC2_CH3_PIN
#else
#define ADC2_CH3_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH4_PIN
#define ADC2_CH4_PIN BSP_ADC2_CH4_PIN
#else
#define ADC2_CH4_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH5_PIN
#define ADC2_CH5_PIN BSP_ADC2_CH5_PIN
#else
#define ADC2_CH5_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH6_PIN
#define ADC2_CH6_PIN BSP_ADC2_CH6_PIN
#else
#define ADC2_CH6_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH7_PIN
#define ADC2_CH7_PIN BSP_ADC2_CH7_PIN
#else
#define ADC2_CH7_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH8_PIN
#define ADC2_CH8_PIN BSP_ADC2_CH8_PIN
#else
#define ADC2_CH8_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH9_PIN
#define ADC2_CH9_PIN BSP_ADC2_CH9_PIN
#else
#define ADC2_CH9_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH10_PIN
#define ADC2_CH10_PIN BSP_ADC2_CH10_PIN
#else
#define ADC2_CH10_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH11_PIN
#define ADC2_CH11_PIN BSP_ADC2_CH11_PIN
#else
#define ADC2_CH11_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH12_PIN
#define ADC2_CH12_PIN BSP_ADC2_CH12_PIN
#else
#define ADC2_CH12_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH13_PIN
#define ADC2_CH13_PIN BSP_ADC2_CH13_PIN
#else
#define ADC2_CH13_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH14_PIN
#define ADC2_CH14_PIN BSP_ADC2_CH14_PIN
#else
#define ADC2_CH14_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH15_PIN
#define ADC2_CH15_PIN BSP_ADC2_CH15_PIN
#else
#define ADC2_CH15_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH16_PIN
#define ADC2_CH16_PIN BSP_ADC2_CH16_PIN
#else
#define ADC2_CH16_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH17_PIN
#define ADC2_CH17_PIN BSP_ADC2_CH17_PIN
#else
#define ADC2_CH17_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH18_PIN
#define ADC2_CH18_PIN BSP_ADC2_CH18_PIN
#else
#define ADC2_CH18_PIN RT_NULL
#endif
#ifdef BSP_ADC2_CH19_PIN
#define ADC2_CH19_PIN BSP_ADC2_CH19_PIN
#else
#define ADC2_CH19_PIN RT_NULL
#endif
#ifndef ADC2_CONFIG
#define ADC2_CONFIG \
{ \
ADC2, \
RCU_ADC2, \
{ \
ADC2_CH0_PIN, \
ADC2_CH1_PIN, \
ADC2_CH2_PIN, \
ADC2_CH3_PIN, \
ADC2_CH4_PIN, \
ADC2_CH5_PIN, \
ADC2_CH6_PIN, \
ADC2_CH7_PIN, \
ADC2_CH8_PIN, \
ADC2_CH9_PIN, \
ADC2_CH10_PIN, \
ADC2_CH11_PIN, \
ADC2_CH12_PIN, \
ADC2_CH13_PIN, \
ADC2_CH14_PIN, \
ADC2_CH15_PIN, \
ADC2_CH16_PIN, \
ADC2_CH17_PIN, \
ADC2_CH18_PIN, \
ADC2_CH19_PIN, \
}, \
&adc2, \
"adc2", \
}
#endif /* ADC2_CONFIG */
#endif /* BSP_USING_ADC2 */
#ifdef __cplusplus
}
#endif
#endif // __ADC_CONFIG_H__

83
828ECO/drivers/include/config/can_config.h

@ -0,0 +1,83 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-22 WangShun compatible with RT-Studio
*/
#ifndef __CAN_CONFIG_H__
#define __CAN_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(BSP_USING_CAN0)
#ifndef BSP_CAN0_RX_PIN
#define BSP_CAN0_RX_PIN "PD0"
#define BSP_CAN0_TX_PIN "PD1"
#define BSP_CAN0_AFIO "AF9"
#endif /* BSP_CAN0_RX_PIN */
#ifndef CAN0_CONFIG
#define CAN0_CONFIG \
{ \
.name = "can0", \
.can_periph = CAN0, \
.tx_pin_name = BSP_CAN0_TX_PIN, \
.rx_pin_name = BSP_CAN0_RX_PIN, \
.alternate = BSP_CAN0_AFIO, \
.device = &dev_can0, \
}
#endif /* CAN0_CONFIG */
#endif /* BSP_USING_CAN0 */
#if defined(BSP_USING_CAN1)
#ifndef BSP_CAN1_RX_PIN
#define BSP_CAN1_RX_PIN "PB5"
#define BSP_CAN1_TX_PIN "PB6"
#define BSP_CAN1_AFIO "AF9"
#endif /* BSP_CAN0_RX_PIN */
#ifndef CAN1_CONFIG
#define CAN1_CONFIG \
{ \
.name = "can1", \
.can_periph = CAN1, \
.tx_pin_name = BSP_CAN1_TX_PIN, \
.rx_pin_name = BSP_CAN1_RX_PIN, \
.alternate = BSP_CAN1_AFIO, \
.device = &dev_can1, \
}
#endif /* CAN1_CONFIG */
#endif /* BSP_USING_CAN1 */
#if defined(BSP_USING_CAN2)
#ifndef BSP_CAN2_RX_PIN
#define BSP_CAN2_RX_PIN "PD12"
#define BSP_CAN2_TX_PIN "PD13"
#define BSP_CAN2_AFIO "AF5"
#endif /* BSP_CAN2_RX_PIN */
#ifndef CAN2_CONFIG
#define CAN2_CONFIG \
{ \
.name = "can2", \
.can_periph = CAN2, \
.tx_pin_name = BSP_CAN2_TX_PIN, \
.rx_pin_name = BSP_CAN2_RX_PIN, \
.alternate = BSP_CAN2_AFIO, \
.device = &dev_can2, \
}
#endif /* CAN2_CONFIG */
#endif /* BSP_USING_CAN2 */
#ifdef __cplusplus
}
#endif
#endif /* __CAN_CONFIG_H__ */

51
828ECO/drivers/include/config/dac_config.h

@ -0,0 +1,51 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-11 kurisaw first version
*/
#ifndef __DAC_CONFIG_H__
#define __DAC_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_DAC0
#ifndef DAC0_CONFIG
#define DAC0_CONFIG \
{ \
.dac_periph = DAC0, \
.name = "dac0", \
.pin_name = BSP_DAC0_PIN, \
.channel = BSP_DAC0_CHANNEL, \
}
#endif /* DAC0_CONFIG */
#endif /* BSP_USING_DAC0 */
#ifdef BSP_USING_DAC1
#ifndef DAC1_CONFIG
#define DAC1_CONFIG \
{ \
.dac_periph = DAC0, \
.name = "dac1", \
.pin_name = BSP_DAC1_PIN, \
.channel = BSP_DAC1_CHANNEL, \
}
#endif /* DAC1_CONFIG */
#endif /* BSP_USING_DAC1 */
#ifdef __cplusplus
}
#endif
#endif /*__DAC_CONFIG_H__ */

59
828ECO/drivers/include/config/enet_config.h

@ -0,0 +1,59 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-10 kurisaw ENET configuration
*/
#ifndef __ENET_CONFIG_H__
#define __ENET_CONFIG_H__
#include "drv_enet.h"
#if defined(RT_USING_SAL) && defined(RT_USING_NETDEV) && defined(RT_USING_LWIP)
#ifdef __cplusplus
extern "C" {
#endif
/* ENET pin configuration table for RMII interface */
const struct enet_pin_config enet0_pins[] =
{
/* ETH_RMII_REF_CLK */ {"PA1", "AF11"},
/* ETH_MDIO */ {"PA2", "AF11"},
/* ETH_RMII_CRS_DV */ {"PA7", "AF11"},
/* ETH_RMII_TX_EN */ {"PG11", "AF11"},
/* ETH_RMII_TXD0 */ {"PB12", "AF11"},
/* ETH_RMII_TXD1 */ {"PG12", "AF11"},
/* ETH_MDC */ {"PC1", "AF11"},
/* ETH_RMII_RXD0 */ {"PC4", "AF11"},
/* ETH_RMII_RXD1 */ {"PC5", "AF11"},
};
/* Clock output pin for PHY */
const struct enet_pin_config enet_clock_pin = {
"PA8", "AF0" /* Clock output for PHY */
};
/* ENET configuration */
const struct enet_config enet0_cfg = {
.pins = enet0_pins,
.pin_count = sizeof(enet0_pins) / sizeof(enet0_pins[0]),
.enet_periph = ENET0,
.enet_clk = RCU_ENET0,
.enet_tx_clk = RCU_ENET0TX,
.enet_rx_clk = RCU_ENET0RX,
.phy_interface = SYSCFG_ENET_PHY_RMII,
.speed = GPIO_OSPEED_100_220MHZ,
.otype = GPIO_OTYPE_PP,
.pupd = GPIO_PUPD_NONE,
};
#ifdef __cplusplus
}
#endif
#endif /* RT_USING_SAL && RT_USING_NETDEV && RT_USING_LWIP */
#endif /* __ENET_CONFIG_H__ */

195
828ECO/drivers/include/config/hwtimer_config.h

@ -0,0 +1,195 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-22 kurisaw initial commit
*/
#ifndef __HWTIMER_CONFIG_H__
#define __HWTIMER_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "drv_hwtimer.h"
#ifdef BSP_USING_HWTIMER0
#ifndef HWTIMER0_CONFIG
#define HWTIMER0_CONFIG \
{ \
"timer0", \
{ \
TIMER0, \
TIMER0_UP_IRQn, \
RCU_TIMER0, \
}, \
{ 0 }, \
{ \
10000000, /* max frequency */ \
1000, /* min frequency */ \
0xFFFF, /* 16-bit counter */ \
HWTIMER_CNTMODE_UP, /* count up mode */ \
}, \
}
#endif /* HWTIMER0_CONFIG */
#endif /* BSP_USING_HWTIMER0 */
#ifdef BSP_USING_HWTIMER1
#ifndef HWTIMER1_CONFIG
#define HWTIMER1_CONFIG \
{ \
"timer1", \
{ \
TIMER1, \
TIMER1_IRQn, \
RCU_TIMER1, \
}, \
{ 0 }, \
{ \
10000000, \
1000, \
0xFFFFFFFF, /* 32-bit counter */ \
HWTIMER_CNTMODE_UP, \
}, \
}
#endif /* HWTIMER1_CONFIG */
#endif /* BSP_USING_HWTIMER1 */
#ifdef BSP_USING_HWTIMER2
#ifndef HWTIMER2_CONFIG
#define HWTIMER2_CONFIG \
{ \
"timer2", \
{ \
TIMER2, \
TIMER2_IRQn, \
RCU_TIMER2, \
}, \
{ 0 }, \
{ \
10000000, \
1000, \
0xFFFF, /* 16-bit counter */ \
HWTIMER_CNTMODE_UP, \
}, \
}
#endif /* HWTIMER2_CONFIG */
#endif /* BSP_USING_HWTIMER2 */
#ifdef BSP_USING_HWTIMER3
#ifndef HWTIMER3_CONFIG
#define HWTIMER3_CONFIG \
{ \
"timer3", \
{ \
TIMER3, \
TIMER3_IRQn, \
RCU_TIMER3, \
}, \
{ 0 }, \
{ \
10000000, \
1000, \
0xFFFF, /* 16-bit counter */ \
HWTIMER_CNTMODE_UP, \
}, \
}
#endif /* HWTIMER3_CONFIG */
#endif /* BSP_USING_HWTIMER3 */
#ifdef BSP_USING_HWTIMER4
#ifndef HWTIMER4_CONFIG
#define HWTIMER4_CONFIG \
{ \
"timer4", \
{ \
TIMER4, \
TIMER4_IRQn, \
RCU_TIMER4, \
}, \
{ 0 }, \
{ \
10000000, \
1000, \
0xFFFFFFFF, /* 32-bit counter */ \
HWTIMER_CNTMODE_UP, \
}, \
}
#endif /* HWTIMER4_CONFIG */
#endif /* BSP_USING_HWTIMER4 */
#ifdef BSP_USING_HWTIMER5
#ifndef HWTIMER5_CONFIG
#define HWTIMER5_CONFIG \
{ \
"timer5", \
{ \
TIMER5, \
TIMER5_IRQn, \
RCU_TIMER5, \
}, \
{ 0 }, \
{ \
10000000, \
1000, \
0xFFFFFFFF, /* 32-bit counter */ \
HWTIMER_CNTMODE_UP, \
}, \
}
#endif /* HWTIMER5_CONFIG */
#endif /* BSP_USING_HWTIMER5 */
#ifdef BSP_USING_HWTIMER6
#ifndef HWTIMER6_CONFIG
#define HWTIMER6_CONFIG \
{ \
"timer6", \
{ \
TIMER6, \
TIMER6_IRQn, \
RCU_TIMER6, \
}, \
{ 0 }, \
{ \
10000000, \
1000, \
0xFFFFFFFF, /* 32-bit counter */ \
HWTIMER_CNTMODE_UP, \
}, \
}
#endif /* HWTIMER6_CONFIG */
#endif /* BSP_USING_HWTIMER6 */
#ifdef BSP_USING_HWTIMER7
#ifndef HWTIMER7_CONFIG
#define HWTIMER7_CONFIG \
{ \
"timer7", \
{ \
TIMER7, \
TIMER7_UP_IRQn, \
RCU_TIMER7, \
}, \
{ 0 }, \
{ \
10000000, \
1000, \
0xFFFF, /* 16-bit counter */ \
HWTIMER_CNTMODE_UP, \
}, \
}
#endif /* HWTIMER7_CONFIG */
#endif /* BSP_USING_HWTIMER7 */
#ifdef __cplusplus
}
#endif
#endif /* __HWTIMER_CONFIG_H__ */

146
828ECO/drivers/include/config/i2c_config.h

@ -0,0 +1,146 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-10 WangShun compatible with RT-Studio
*/
#ifndef __I2C_CONFIG_H__
#define __I2C_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_I2C0
#ifndef BSP_I2C0_SCL_PIN
#define BSP_I2C0_SCL_PIN "PB6"
#define BSP_I2C0_SDA_PIN "PB7"
#define BSP_I2C0_AFIO "AF4"
#endif /* BSP_I2C0_SCL_PIN */
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.i2c_periph = I2C0, \
.per_clk = RCU_I2C0, \
.scl_pin_name = BSP_I2C0_SCL_PIN, \
.sda_pin_name = BSP_I2C0_SDA_PIN, \
.alternate = BSP_I2C0_AFIO, \
.i2c_bus = &i2c0, \
.device_name = "i2c0", \
}
#endif /* I2C0_CONFIG */
#endif /* BSP_USING_I2C0 */
#ifdef BSP_USING_I2C1
#ifndef BSP_I2C1_SCL_PIN
#define BSP_I2C1_SCL_PIN "PH4"
#define BSP_I2C1_SDA_PIN "PB11"
#define BSP_I2C1_AFIO "AF4"
#endif /* BSP_I2C1_SCL_PIN */
#ifndef I2C1_CONFIG
#define I2C1_CONFIG \
{ \
.i2c_periph = I2C1, \
.per_clk = RCU_I2C1, \
.scl_pin_name = BSP_I2C1_SCL_PIN, \
.sda_pin_name = BSP_I2C1_SDA_PIN, \
.alternate = BSP_I2C1_AFIO, \
.i2c_bus = &i2c1, \
.device_name = "i2c1", \
}
#endif /* I2C1_CONFIG */
#endif /* BSP_USING_I2C1 */
#ifdef BSP_USING_I2C2
#ifndef BSP_I2C2_SCL_PIN
#define BSP_I2C2_SCL_PIN "PA8"
#define BSP_I2C2_SDA_PIN "PC9"
#define BSP_I2C2_AFIO "AF4"
#endif /* BSP_I2C2_SCL_PIN */
#ifndef I2C2_CONFIG
#define I2C2_CONFIG \
{ \
.i2c_periph = I2C2, \
.per_clk = RCU_I2C2, \
.scl_pin_name = BSP_I2C2_SCL_PIN, \
.sda_pin_name = BSP_I2C2_SDA_PIN, \
.alternate = BSP_I2C2_AFIO, \
.i2c_bus = &i2c2, \
.device_name = "i2c2", \
}
#endif /* I2C2_CONFIG */
#endif /* BSP_USING_I2C2 */
#ifdef BSP_USING_I2C3
#ifndef BSP_I2C3_SCL_PIN
#define BSP_I2C3_SCL_PIN "PD12"
#define BSP_I2C3_SDA_PIN "PD13"
#define BSP_I2C3_AFIO "AF4"
#endif /* BSP_I2C3_SCL_PIN */
#ifndef I2C3_CONFIG
#define I2C3_CONFIG \
{ \
.i2c_periph = I2C3, \
.per_clk = RCU_I2C3, \
.scl_pin_name = BSP_I2C3_SCL_PIN, \
.sda_pin_name = BSP_I2C3_SDA_PIN, \
.alternate = BSP_I2C3_AFIO, \
.i2c_bus = &i2c3, \
.device_name = "i2c3", \
}
#endif /* I2C3_CONFIG */
#endif /* BSP_USING_I2C3 */
#ifdef BSP_USING_I2C4
#ifndef BSP_I2C4_SCL_PIN
#define BSP_I2C4_SCL_PIN "PG7"
#define BSP_I2C4_SDA_PIN "PG8"
#define BSP_I2C4_AFIO "AF6"
#endif /* BSP_I2C4_SCL_PIN */
#ifndef I2C4_CONFIG
#define I2C4_CONFIG \
{ \
.i2c_periph = I2C4, \
.per_clk = RCU_I2C4, \
.scl_pin_name = BSP_I2C4_SCL_PIN, \
.sda_pin_name = BSP_I2C4_SDA_PIN, \
.alternate = BSP_I2C4_AFIO, \
.i2c_bus = &i2c4, \
.device_name = "i2c4", \
}
#endif /* I2C4_CONFIG */
#endif /* BSP_USING_I2C4 */
#ifdef BSP_USING_I2C5
#ifndef BSP_I2C5_SCL_PIN
#define BSP_I2C5_SCL_PIN "PF11"
#define BSP_I2C5_SDA_PIN "PF12"
#define BSP_I2C5_AFIO "AF4"
#endif /* BSP_I2C5_SCL_PIN */
#ifndef I2C5_CONFIG
#define I2C5_CONFIG \
{ \
.i2c_periph = I2C5, \
.per_clk = RCU_I2C5, \
.scl_pin_name = BSP_I2C5_SCL_PIN, \
.sda_pin_name = BSP_I2C5_SDA_PIN, \
.alternate = BSP_I2C5_AFIO, \
.i2c_bus = &i2c5, \
.device_name = "i2c5", \
}
#endif /* I2C5_CONFIG */
#endif /* BSP_USING_I2C5 */
#ifdef __cplusplus
}
#endif
#endif /*__I2C_CONFIG_H__ */

145
828ECO/drivers/include/config/pwm_config.h

@ -0,0 +1,145 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-11 kurisaw compatible with RT-Studio
*/
#ifndef __PWM_CONFIG_H__
#define __PWM_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_PWM0
#ifndef PWM0_CONFIG
#define PWM0_CONFIG \
{ \
.timer_periph = TIMER0, \
.name = "pwm0", \
.timer_clk = RCU_TIMER0, \
.pin_name = BSP_PWM0_PIN, \
.channel = BSP_PWM0_CHANNEL, \
.alternate = BSP_PWM0_AFIO, \
}
#endif /* PWM0_CONFIG */
#endif /* BSP_USING_PWM0 */
#ifdef BSP_USING_PWM1
#ifndef PWM1_CONFIG
#define PWM1_CONFIG \
{ \
.timer_periph = TIMER1, \
.name = "pwm1", \
.timer_clk = RCU_TIMER1, \
.pin_name = BSP_PWM1_PIN, \
.channel = BSP_PWM1_CHANNEL, \
.alternate = BSP_PWM1_AFIO, \
}
#endif /* PWM1_CONFIG */
#endif /* BSP_USING_PWM1 */
#ifdef BSP_USING_PWM2
#ifndef PWM2_CONFIG
#define PWM2_CONFIG \
{ \
.timer_periph = TIMER2, \
.name = "pwm2", \
.timer_clk = RCU_TIMER2, \
.pin_name = BSP_PWM2_PIN, \
.channel = BSP_PWM2_CHANNEL, \
.alternate = BSP_PWM2_AFIO, \
}
#endif /* PWM2_CONFIG */
#endif /* BSP_USING_PWM2 */
#ifdef BSP_USING_PWM3
#ifndef PWM3_CONFIG
#define PWM3_CONFIG \
{ \
.timer_periph = TIMER3, \
.name = "pwm3", \
.timer_clk = RCU_TIMER3, \
.pin_name = BSP_PWM3_PIN, \
.channel = BSP_PWM3_CHANNEL, \
.alternate = BSP_PWM3_AFIO, \
}
#endif /* PWM3_CONFIG */
#endif /* BSP_USING_PWM3 */
#ifdef BSP_USING_PWM4
#ifndef PWM4_CONFIG
#define PWM4_CONFIG \
{ \
.timer_periph = TIMER4, \
.name = "pwm4", \
.timer_clk = RCU_TIMER4, \
.pin_name = BSP_PWM4_PIN, \
.channel = BSP_PWM4_CHANNEL, \
.alternate = BSP_PWM4_AFIO, \
}
#endif /* PWM4_CONFIG */
#endif /* BSP_USING_PWM4 */
#ifdef BSP_USING_PWM5
#ifndef PWM5_CONFIG
#define PWM5_CONFIG \
{ \
.timer_periph = TIMER5, \
.name = "pwm5", \
.timer_clk = RCU_TIMER5, \
.pin_name = BSP_PWM5_PIN, \
.channel = BSP_PWM5_CHANNEL, \
.alternate = BSP_PWM5_AFIO, \
}
#endif /* PWM5_CONFIG */
#endif /* BSP_USING_PWM5 */
#ifdef BSP_USING_PWM6
#ifndef PWM6_CONFIG
#define PWM6_CONFIG \
{ \
.timer_periph = TIMER6, \
.name = "pwm6", \
.timer_clk = RCU_TIMER6, \
.pin_name = BSP_PWM6_PIN, \
.channel = BSP_PWM6_CHANNEL, \
.alternate = BSP_PWM6_AFIO, \
}
#endif /* PWM6_CONFIG */
#endif /* BSP_USING_PWM6 */
#ifdef BSP_USING_PWM7
#ifndef PWM7_CONFIG
#define PWM7_CONFIG \
{ \
.timer_periph = TIMER7, \
.name = "pwm7", \
.timer_clk = RCU_TIMER7, \
.pin_name = BSP_PWM7_PIN, \
.channel = BSP_PWM7_CHANNEL, \
.alternate = BSP_PWM7_AFIO, \
}
#endif /* PWM7_CONFIG */
#endif /* BSP_USING_PWM7 */
#ifdef __cplusplus
}
#endif
#endif /*__PWM_CONFIG_H__ */

178
828ECO/drivers/include/config/spi_config.h

@ -0,0 +1,178 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 SummerGift first version
* 2019-01-03 zylx modify DMA support
* 2025-10-10 WangShun compatible with RT-Studio
*/
#ifndef __SPI_CONFIG_H__
#define __SPI_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef RT_SPI_USING_DMA
#define IF_SPI_DMA(x) x
#else
#define IF_SPI_DMA(x)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_SPI0
#ifndef BSP_SPI0_SCK_PIN
#define BSP_SPI0_SCK_PIN "PA5"
#define BSP_SPI0_MISO_PIN "PA6"
#define BSP_SPI0_MOSI_PIN "PA7"
#define BSP_SPI0_AFIO "AF5"
#endif /* BSP_SPI0_SCK_PIN */
#ifndef SPI0_BUS_CONFIG
#define SPI0_BUS_CONFIG \
{ \
.spi_periph = SPI0, \
.bus_name = "spi0", \
.spi_clk = RCU_SPI0, \
.spi_bus = &spi_bus0, \
.sck_pin_name = BSP_SPI0_SCK_PIN, \
.miso_pin_name = BSP_SPI0_MISO_PIN, \
.mosi_pin_name = BSP_SPI0_MOSI_PIN, \
.alternate = BSP_SPI0_AFIO, \
IF_SPI_DMA(.spi_dma = &spi_dma[0]) \
}
#endif /* SPI0_BUS_CONFIG */
#endif /* BSP_USING_SPI0 */
#ifdef BSP_USING_SPI1
#ifndef BSP_SPI1_SCK_PIN
#define BSP_SPI1_SCK_PIN "PB13"
#define BSP_SPI1_MISO_PIN "PB14"
#define BSP_SPI1_MOSI_PIN "PB15"
#define BSP_SPI1_AFIO "AF5"
#endif /* BSP_SPI1_SCK_PIN */
#ifndef SPI1_BUS_CONFIG
#define SPI1_BUS_CONFIG \
{ \
.spi_periph = SPI1, \
.bus_name = "spi1", \
.spi_clk = RCU_SPI1, \
.spi_bus = &spi_bus1, \
.sck_pin_name = BSP_SPI1_SCK_PIN, \
.miso_pin_name = BSP_SPI1_MISO_PIN, \
.mosi_pin_name = BSP_SPI1_MOSI_PIN, \
.alternate = BSP_SPI1_AFIO, \
IF_SPI_DMA(.spi_dma = &spi_dma[1]) \
}
#endif /* SPI1_BUS_CONFIG */
#endif /* BSP_USING_SPI1 */
#ifdef BSP_USING_SPI2
#ifndef BSP_SPI2_SCK_PIN
#define BSP_SPI2_SCK_PIN "PB3"
#define BSP_SPI2_MISO_PIN "PB4"
#define BSP_SPI2_MOSI_PIN "PB5"
#define BSP_SPI2_AFIO "AF6"
#endif /* BSP_SPI1_SCK_PIN */
#ifndef SPI2_BUS_CONFIG
#define SPI2_BUS_CONFIG \
{ \
.spi_periph = SPI2, \
.bus_name = "spi2", \
.spi_clk = RCU_SPI2, \
.spi_bus = &spi_bus2, \
.sck_pin_name = BSP_SPI2_SCK_PIN, \
.miso_pin_name = BSP_SPI2_MISO_PIN, \
.mosi_pin_name = BSP_SPI2_MOSI_PIN, \
.alternate = BSP_SPI2_AFIO, \
IF_SPI_DMA(.spi_dma = &spi_dma[2]) \
}
#endif /* SPI2_BUS_CONFIG */
#endif /* BSP_USING_SPI2 */
#ifdef BSP_USING_SPI3
#ifndef BSP_SPI3_SCK_PIN
#define BSP_SPI3_SCK_PIN "PE12"
#define BSP_SPI3_MISO_PIN "PE13"
#define BSP_SPI3_MOSI_PIN "PE14"
#define BSP_SPI3_AFIO "AF5"
#endif /* BSP_SPI3_SCK_PIN */
#ifndef SPI3_BUS_CONFIG
#define SPI3_BUS_CONFIG \
{ \
.spi_periph = SPI3, \
.bus_name = "spi3", \
.spi_clk = RCU_SPI3, \
.spi_bus = &spi_bus3, \
.sck_pin_name = BSP_SPI3_SCK_PIN, \
.miso_pin_name = BSP_SPI3_MISO_PIN, \
.mosi_pin_name = BSP_SPI3_MOSI_PIN, \
.alternate = BSP_SPI3_AFIO, \
IF_SPI_DMA(.spi_dma = &spi_dma[3]) \
}
#endif /* SPI3_BUS_CONFIG */
#endif /* BSP_USING_SPI3 */
#ifdef BSP_USING_SPI4
#ifndef BSP_SPI4_SCK_PIN
#define BSP_SPI4_SCK_PIN "PF7"
#define BSP_SPI4_MISO_PIN "PF8"
#define BSP_SPI4_MOSI_PIN "PF9"
#define BSP_SPI4_AFIO "AF5"
#endif /* BSP_SPI4_SCK_PIN */
#ifndef SPI4_BUS_CONFIG
#define SPI4_BUS_CONFIG \
{ \
.spi_periph = SPI4, \
.bus_name = "spi4", \
.spi_clk = RCU_SPI4, \
.spi_bus = &spi_bus4, \
.sck_pin_name = BSP_SPI4_SCK_PIN, \
.miso_pin_name = BSP_SPI4_MISO_PIN, \
.mosi_pin_name = BSP_SPI4_MOSI_PIN, \
.alternate = BSP_SPI4_AFIO, \
IF_SPI_DMA(.spi_dma = &spi_dma[4]) \
}
#endif /* SPI4_BUS_CONFIG */
#endif /* BSP_USING_SPI4 */
#ifdef BSP_USING_SPI5
#ifndef BSP_SPI5_SCK_PIN
#define BSP_SPI5_SCK_PIN "PG13"
#define BSP_SPI5_MISO_PIN "PG12"
#define BSP_SPI5_MOSI_PIN "PG14"
#define BSP_SPI5_AFIO "AF5"
#endif /* BSP_SPI5_SCK_PIN */
#ifndef SPI5_BUS_CONFIG
#define SPI5_BUS_CONFIG \
{ \
.spi_periph = SPI5, \
.bus_name = "spi5", \
.spi_clk = RCU_SPI5, \
.spi_bus = &spi_bus5, \
.sck_pin_name = BSP_SPI5_SCK_PIN, \
.miso_pin_name = BSP_SPI5_MISO_PIN, \
.mosi_pin_name = BSP_SPI5_MOSI_PIN, \
.alternate = BSP_SPI5_AFIO, \
IF_SPI_DMA(.spi_dma = &spi_dma[5]) \
}
#endif /* SPI5_BUS_CONFIG */
#endif /* BSP_USING_SPI5 */
#ifdef __cplusplus
}
#endif
#endif /*__SPI_CONFIG_H__ */

204
828ECO/drivers/include/config/uart_config.h

@ -0,0 +1,204 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-10-30 SummerGift first version
* 2019-01-03 zylx modify dma support
* 2025-10-09 WangShun compatible with RT-Studio
*/
#ifndef __UART_CONFIG_H__
#define __UART_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BSP_UART0_AFIO
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E
#define BSP_UART0_AFIO "AF4"
#elif defined SOC_SERIES_GD32E23x
#define BSP_UART0_AFIO "AF1"
#endif
#endif
#ifndef BSP_UART1_AFIO
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E
#define BSP_UART1_AFIO "AF7"
#elif defined SOC_SERIES_GD32E23x
#define BSP_UART1_AFIO "AF1"
#endif
#endif
#ifndef BSP_UART2_AFIO
#define BSP_UART2_AFIO "AF7"
#endif
#ifndef BSP_UART3_AFIO
#define BSP_UART3_AFIO "AF8"
#endif
#ifndef BSP_UART4_AFIO
#define BSP_UART4_AFIO "AF8"
#endif
#ifndef BSP_UART5_AFIO
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx
#define BSP_UART5_AFIO "AF8"
#elif defined (SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
#define BSP_UART5_AFIO "AF7"
#endif
#endif
#ifndef BSP_UART6_AFIO
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx
#define BSP_UART6_AFIO "AF8"
#elif defined (SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
#define BSP_UART6_AFIO "AF7"
#endif
#endif
#ifndef BSP_UART7_AFIO
#define BSP_UART7_AFIO "AF8"
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.uart_periph = USART0, \
.irqn = USART0_IRQn, \
.per_clk = RCU_USART0, \
.tx_pin_name = BSP_UART0_TX_PIN, \
.rx_pin_name = BSP_UART0_RX_PIN, \
.alternate = BSP_UART0_AFIO, \
.serial = &serial0, \
.device_name = "uart0", \
}
#endif /* UART0_CONFIG */
#endif /* BSP_USING_UART0 */
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.uart_periph = USART1, \
.irqn = USART1_IRQn, \
.per_clk = RCU_USART1, \
.tx_pin_name = BSP_UART1_TX_PIN, \
.rx_pin_name = BSP_UART1_RX_PIN, \
.alternate = BSP_UART1_AFIO, \
.serial = &serial1, \
.device_name = "uart1", \
}
#endif /* UART1_CONFIG */
#endif /* BSP_USING_UART1 */
#if defined(BSP_USING_UART2)
#ifndef UART2_CONFIG
#define UART2_CONFIG \
{ \
.uart_periph = USART2, \
.irqn = USART2_IRQn, \
.per_clk = RCU_USART2, \
.tx_pin_name = BSP_UART2_TX_PIN, \
.rx_pin_name = BSP_UART2_RX_PIN, \
.alternate = BSP_UART2_AFIO, \
.serial = &serial2, \
.device_name = "uart2", \
}
#endif /* UART2_CONFIG */
#endif /* BSP_USING_UART2 */
#if defined(BSP_USING_UART3)
#ifndef UART3_CONFIG
#define UART3_CONFIG \
{ \
.uart_periph = UART3, \
.irqn = UART3_IRQn, \
.per_clk = RCU_UART3, \
.tx_pin_name = BSP_UART3_TX_PIN, \
.rx_pin_name = BSP_UART3_RX_PIN, \
.alternate = BSP_UART3_AFIO, \
.serial = &serial3, \
.device_name = "uart3", \
}
#endif /* UART3_CONFIG */
#endif /* BSP_USING_UART3 */
#if defined(BSP_USING_UART4)
#ifndef UART4_CONFIG
#define UART4_CONFIG \
{ \
.uart_periph = UART4, \
.irqn = UART4_IRQn, \
.per_clk = RCU_UART4, \
.tx_pin_name = BSP_UART4_TX_PIN, \
.rx_pin_name = BSP_UART4_RX_PIN, \
.alternate = BSP_UART4_AFIO, \
.serial = &serial4, \
.device_name = "uart4", \
}
#endif /* UART4_CONFIG */
#endif /* BSP_USING_UART4 */
#if defined(BSP_USING_UART5)
#ifndef UART5_CONFIG
#define UART5_CONFIG \
{ \
.uart_periph = USART5, \
.irqn = USART5_IRQn, \
.per_clk = RCU_USART5, \
.tx_pin_name = BSP_UART5_TX_PIN, \
.rx_pin_name = BSP_UART5_RX_PIN, \
.alternate = BSP_UART5_AFIO, \
.serial = &serial5, \
.device_name = "uart5", \
}
#endif /* UART5_CONFIG */
#endif /* BSP_USING_UART5 */
#if defined(BSP_USING_UART6)
#ifndef UART6_CONFIG
#define UART6_CONFIG \
{ \
.uart_periph = UART6, \
.irqn = UART6_IRQn, \
.per_clk = RCU_UART6, \
.tx_pin_name = BSP_UART6_TX_PIN, \
.rx_pin_name = BSP_UART6_RX_PIN, \
.alternate = BSP_UART6_AFIO, \
.serial = &serial6, \
.device_name = "uart6", \
}
#endif /* UART6_CONFIG */
#endif /* BSP_USING_UART6 */
#if defined(BSP_USING_UART7)
#ifndef UART7_CONFIG
#define UART7_CONFIG \
{ \
.uart_periph = UART7, \
.irqn = UART7_IRQn, \
.per_clk = RCU_UART7, \
.tx_pin_name = BSP_UART7_TX_PIN, \
.rx_pin_name = BSP_UART7_RX_PIN, \
.alternate = BSP_UART7_AFIO, \
.serial = &serial7, \
.device_name = "uart7", \
}
#endif /* UART7_CONFIG */
#endif /* BSP_USING_UART7 */
#ifdef __cplusplus
}
#endif
#endif /* __UART_CONFIG_H__ */

40
828ECO/drivers/include/drv_adc.h

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-05-03 BruceOu first implementation
* 2025-10-22 kurisaw optimize multi-channel GPIO configuration
*/
#ifndef __DRV_ADC_H__
#define __DRV_ADC_H__
#include <rthw.h>
#include <rtthread.h>
#include <board.h>
#include "drv_gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_EXTERN_ADC_CHANNEL 20
/* gd32 adc driver class */
struct gd32_adc
{
uint32_t adc_periph;
rcu_periph_enum adc_clk;
const char *adc_pins[MAX_EXTERN_ADC_CHANNEL];
struct rt_adc_device *adc;
char *device_name;
};
#ifdef __cplusplus
}
#endif
#endif /* __DRV_ADC_H__ */

109
828ECO/drivers/include/drv_can.h

@ -0,0 +1,109 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef __DRV_CAN_H__
#define __DRV_CAN_H__
#include <rtdevice.h>
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef RT_USING_CAN
/* Aliases for __IRQn */
#if defined(BSP_USING_CAN0) || defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2)
/* BSP_USING_CAN0 */
#define CAN0_TX_IRQn CAN0_Message_IRQn
#define CAN0_RX_IRQn CAN0_Message_IRQn
#define CAN0_ERROR_IRQn CAN0_Error_IRQn
/* BSP_USING_CAN1 */
#define CAN1_TX_IRQn CAN1_Message_IRQn
#define CAN1_RX_IRQn CAN1_Message_IRQn
#define CAN1_ERROR_IRQn CAN1_Error_IRQn
/* BSP_USING_CAN2 */
#define CAN2_TX_IRQn CAN2_Message_IRQn
#define CAN2_RX_IRQn CAN2_Message_IRQn
#define CAN2_ERROR_IRQn CAN2_Error_IRQn
#endif
struct gd32_baud_rate_tab
{
uint32_t baud_rate;
uint8_t resync_jump_width;
uint8_t prop_time_segment;
uint8_t time_segment_1;
uint8_t time_segment_2;
uint32_t prescaler;
};
#ifdef RT_CAN_USING_CANFD
typedef struct
{
rt_uint32_t baud;
rt_uint8_t sjw;
rt_uint8_t prop;
rt_uint8_t seg1;
rt_uint8_t seg2;
rt_uint16_t prescaler;
} gd32_fd_data_baud_t;
enum CANFD_BAUD
{
CANFD_5MBaud = 5000UL * 1000, /* 5 MBit/sec */
CANFD_4MBaud = 4000UL * 1000, /* 4 MBit/sec */
CANFD_3MBaud = 3000UL * 1000, /* 3 MBit/sec */
CANFD_2MBaud = 2000UL * 1000, /* 2 MBit/sec */
CANFD_1MBaud = 1000UL * 1000, /* 1 MBit/sec */
CANFD_800kBaud = 1000UL * 800, /* 800 kBit/sec */
CANFD_500kBaud = 1000UL * 500, /* 500 kBit/sec */
CANFD_250kBaud = 1000UL * 250, /* 250 kBit/sec */
CANFD_125kBaud = 1000UL * 125, /* 125 kBit/sec */
CANFD_100kBaud = 1000UL * 100, /* 100 kBit/sec */
CANFD_50kBaud = 1000UL * 50, /* 50 kBit/sec */
CANFD_20kBaud = 1000UL * 20, /* 20 kBit/sec */
CANFD_10kBaud = 1000UL * 10 /* 10 kBit/sec */
};
#endif
/* gd32 can device */
typedef struct
{
char *name;
const char *tx_pin_name; /* can pin name */
const char *rx_pin_name; /* rx pin name */
const char *alternate;
uint32_t can_periph;
can_parameter_struct can_init;
can_fifo_parameter_struct can_fifo;
can_operation_modes_enum mode;
can_mailbox_descriptor_struct tx_message[16];
can_mailbox_descriptor_struct rx_message[16];
rt_uint8_t rx_message_valid[16];
void (*filter_cb)(uint32_t can_periph);
#ifdef RT_CAN_USING_CANFD
can_fd_parameter_struct can_fd_init;
rt_uint8_t fd_enabled;
rt_uint8_t fd_rx_buf[16][64];
#endif
struct rt_can_device *device; /* can device */
} gd32_can_struct;
void can_gpio_config(void);
int rt_hw_can_init(void);
#endif /* RT_USING_CAN */
#ifdef __cplusplus
}
#endif
#endif /* __DRV_CAN_H__ */

40
828ECO/drivers/include/drv_common.h

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-09-0 WangShun first implementation
*/
#ifndef __DRV_COMMON_H__
#define __DRV_COMMON_H__
#include "drv_usart.h"
#include "drv_gpio.h"
#include <board.h>
#define GD32_FLASH_START_ADRESS ROM_START
#define GD32_FLASH_SIZE ROM_SIZE
#define GD32_FLASH_END_ADDRESS ROM_END
#define GD32_SRAM_SIZE RAM_SIZE
#define GD32_SRAM_START RAM_START
#define GD32_SRAM_END RAM_END
#ifdef __ARMCC_VERSION
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section="HEAP"
#define HEAP_BEGIN (__segment_end("HEAP"))
#else
extern int __bss_end;
#define HEAP_BEGIN (&__bss_end)
#endif
#define HEAP_END GD32_SRAM_END
#endif /* __DRV_COMMON_H__ */

21
828ECO/drivers/include/drv_config.h

@ -0,0 +1,21 @@
/*
* drv_config.h for GD32 platform
*/
#ifndef __DRV_CONFIG_H__
#define __DRV_CONFIG_H__
#include <board.h>
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Include peripheral configuration headers under drivers/include/config */
#include "config/uart_config.h"
#ifdef __cplusplus
}
#endif
#endif /* __DRV_CONFIG_H__ */

41
828ECO/drivers/include/drv_dac.h

@ -0,0 +1,41 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-11 kurisaw first version
*/
#ifndef __DRV_DAC_H__
#define __DRV_DAC_H__
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(RT_USING_DAC)
/* gd32 dac driver class */
struct gd32_dac
{
struct rt_dac_device dac_device;
uint32_t dac_periph;
char *name;
const char *pin_name;
rt_int16_t channel;
};
#endif
#ifdef __cplusplus
}
#endif
#endif /* __DRV_DAC_H__ */

58
828ECO/drivers/include/drv_dma.h

@ -0,0 +1,58 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-03-19 Evlers first implementation
*/
#ifndef _DRV_DMA_H_
#define _DRV_DMA_H_
#if defined SOC_SERIES_GD32E23x
#define DRV_DMA_CONFIG(chx) \
(struct dma_config)
{ \
.periph = DMA, \
.rcu = RCU_DMA, \
.channel = DMA_CH##chx, \
.irq = ((chx) == 0 ? DMA_Channel0_IRQn : \
(chx) == 1 ? DMA_Channel1_2_IRQn : \
(chx) == 2 ? DMA_Channel1_2_IRQn : \
(chx) == 3 ? DMA_Channel3_4_IRQn : \
(chx) == 4 ? DMA_Channel3_4_IRQn : (IRQn_Type)0) \
}
struct dma_config
{
uint32_t periph;
rcu_periph_enum rcu;
dma_channel_enum channel;
IRQn_Type irq;
};
#else
#define DRV_DMA_CONFIG(dmax, chx, subx) { \
.periph = DMA##dmax, \
.channel = DMA_CH##chx, \
.rcu = RCU_DMA##dmax, \
.subperiph = DMA_SUBPERI##subx, \
.irq = DMA##dmax##_Channel##chx##_IRQn, \
}
struct dma_config
{
uint32_t periph;
rcu_periph_enum rcu;
dma_channel_enum channel;
dma_subperipheral_enum subperiph;
IRQn_Type irq;
};
#endif
#endif /* _DRV_DMA_H_ */

98
828ECO/drivers/include/drv_enet.h

@ -0,0 +1,98 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-10 kurisaw the first version
*/
#ifndef __DRV_ENET_H__
#define __DRV_ENET_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#if defined(RT_USING_SAL) && defined(RT_USING_NETDEV) && defined(RT_USING_LWIP)
#ifdef __cplusplus
extern "C" {
#endif
#include "gd32h7xx.h"
#include "synopsys_emac.h"
#define EMAC_RXBUFNB 5
#define EMAC_TXBUFNB 5
#define EMAC_PHY_AUTO 0
#define EMAC_PHY_10MBIT 1
#define EMAC_PHY_100MBIT 2
#define MAX_ADDR_LEN 6
/* ENET pin configuration structure */
struct enet_pin_config
{
const char *pin_name; /* Pin name in format "PxY" */
const char *alternate; /* Alternate function in format "AFx" */
};
/* ENET configuration structure */
struct enet_config
{
const struct enet_pin_config *pins;
uint32_t pin_count;
uint32_t enet_periph;
rcu_periph_enum enet_clk;
rcu_periph_enum enet_tx_clk;
rcu_periph_enum enet_rx_clk;
uint32_t phy_interface;
uint32_t speed; /* GPIO speed - common for all pins */
uint8_t otype; /* Output type - common for all pins */
uint8_t pupd; /* Pull-up/pull-down - common for all pins */
};
struct gd32_emac
{
/* inherit from Ethernet device */
struct eth_device parent;
__ALIGNED(4)
rt_uint8_t phy_mode;
/* interface address info. */
__ALIGNED(4)
rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
const struct enet_pin_config *pins;
uint32_t pin_count;
struct rt_synopsys_eth *ETHERNET_MAC;
IRQn_Type ETHER_MAC_IRQ;
EMAC_DMADESCTypeDef *DMATxDescToSet;
EMAC_DMADESCTypeDef *DMARxDescToGet;
#pragma pack(4)
EMAC_DMADESCTypeDef DMARxDscrTab[EMAC_RXBUFNB];
#pragma pack(4)
EMAC_DMADESCTypeDef DMATxDscrTab[EMAC_TXBUFNB];
#pragma pack(4)
rt_uint8_t Rx_Buff[EMAC_RXBUFNB][EMAC_MAX_PACKET_SIZE];
#pragma pack(4)
rt_uint8_t Tx_Buff[EMAC_TXBUFNB][EMAC_MAX_PACKET_SIZE];
struct rt_semaphore tx_buf_free;
};
/* Function declarations */
rt_err_t gd32_enet_gpio_init(struct gd32_emac *emac);
const struct enet_config *gd32_get_enet_config(void);
#ifdef __cplusplus
}
#endif
#endif /* RT_USING_SAL && RT_USING_NETDEV && RT_USING_LWIP */
#endif /* __DRV_ENET_H__ */

93
828ECO/drivers/include/drv_gpio.h

@ -0,0 +1,93 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-20 BruceOu the first version
*/
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined SOC_SERIES_GD32F10x
#include "gd32f10x_gpio.h"
#elif defined SOC_SERIES_GD32F20x
#include "gd32f20x_gpio.h"
#elif defined SOC_SERIES_GD32F30x
#include "gd32f30x_gpio.h"
#elif defined SOC_SERIES_GD32F4xx
#include "gd32f4xx_gpio.h"
#elif defined SOC_SERIES_GD32H7xx
#include "gd32h7xx_gpio.h"
#elif defined SOC_SERIES_GD32H75e
#include "gd32h75e_gpio.h"
#elif defined SOC_SERIES_GD32E50x
#include "gd32e50x_gpio.h"
#elif defined SOC_SERIES_GD32F5xx
#include "gd32f5xx_gpio.h"
#elif defined SOC_SERIES_GD32E23x
#include "gd32e23x_gpio.h"
#endif
#define __GD32_PORT(port) GPIO##port
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32H7xx
#define GD32_PIN(index, port, pin) {index, RCU_GPIO##port, \
GPIO##port, GPIO_PIN_##pin, \
EXTI_SOURCE_GPIO##port, \
EXTI_SOURCE_PIN##pin, \
EXTI_##pin}
#else
#define GD32_PIN(index, port, pin) {index, RCU_GPIO##port, \
GPIO##port, GPIO_PIN_##pin, \
GPIO_PORT_SOURCE_GPIO##port, \
GPIO_PIN_SOURCE_##pin}
#endif
#define GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0, 0, 0}
#define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__GD32_PORT(PORTx) - (rt_base_t)GPIO_BASE)/(0x0400UL) )) + PIN)
#define PIN_PORT(pin) ((uint8_t)(((pin) >> 4) & 0xFu))
#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu))
#define PIN_GDPORT(pin) (GPIO_BASE + (0x400u * PIN_PORT(pin)))
#define PIN_GDPIN(pin) ((uint16_t)(1u << PIN_NO(pin)))
struct pin_index
{
rt_int16_t index;
rcu_periph_enum clk;
rt_uint32_t gpio_periph;
rt_uint32_t pin;
rt_uint8_t port_src;
rt_uint8_t pin_src;
rt_uint32_t exit_line;
};
struct pin_irq_map
{
rt_uint16_t pinbit;
IRQn_Type irqno;
};
int get_pin_config(const char *pin_name, uint32_t *port, uint32_t *pin, rcu_periph_enum *clk);
int pin_alternate_config(const char *alternate, uint32_t *af);
#ifdef __cplusplus
}
#endif
#endif /* __DRV_GPIO_H__ */

72
828ECO/drivers/include/drv_hwtimer.h

@ -0,0 +1,72 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-22 kurisaw first version
*/
#ifndef __DRV_HWTIMER_H__
#define __DRV_HWTIMER_H__
#include <rthw.h>
#include <rtdevice.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef RT_USING_HWTIMER
typedef struct
{
uint32_t reg_base;
IRQn_Type irqn;
rcu_periph_enum rcu;
} gd32_hwtimer_data;
typedef struct
{
char dev_name[RT_NAME_MAX];
const gd32_hwtimer_data hw_data;
rt_hwtimer_t hwtimer_dev;
const struct rt_hwtimer_info hwtimer_info;
} gd32_hwtimer_device;
enum timer_index
{
#ifdef BSP_USING_HWTIMER0
TIM0_INDEX,
#endif
#ifdef BSP_USING_HWTIMER1
TIM1_INDEX,
#endif
#ifdef BSP_USING_HWTIMER2
TIM2_INDEX,
#endif
#ifdef BSP_USING_HWTIMER3
TIM3_INDEX,
#endif
#ifdef BSP_USING_HWTIMER4
TIM4_INDEX,
#endif
#ifdef BSP_USING_HWTIMER5
TIM5_INDEX,
#endif
#ifdef BSP_USING_HWTIMER6
TIM6_INDEX,
#endif
#ifdef BSP_USING_HWTIMER7
TIM7_INDEX,
#endif
};
#endif
#ifdef __cplusplus
}
#endif
#endif /* __DRV_HWTIMER_H__ */

43
828ECO/drivers/include/drv_i2c.h

@ -0,0 +1,43 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-12-20 BruceOu the first version
* 2025-10-10 WangShun compatible with RT-Studio
*/
#ifndef __DRV_I2C__
#define __DRV_I2C__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
/* GD32 i2c driver */
struct gd32_i2c_bus
{
uint32_t i2c_periph;
rcu_periph_enum per_clk;
const char *scl_pin_name; /* scl pin name */
const char *sda_pin_name; /* sda pin name */
const char *alternate; /* afio name */
struct rt_i2c_bus_device *i2c_bus;
char *device_name;
};
#ifdef __cplusplus
}
#endif
#endif /* __DRV_I2C__ */

66
828ECO/drivers/include/drv_lcd.h

@ -0,0 +1,66 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef __DRV_LCD_H__
#define __DRV_LCD_H__
#include <board.h>
#if defined(SOC_SERIES_GD32H7xx)
#include "gd32h7xx_tli.h"
#include "gd32h7xx_ipa.h"
#endif
#define HORIZONTAL_SYNCHRONOUS_PULSE 41
#define HORIZONTAL_BACK_PORCH 2
#define ACTIVE_WIDTH 480
#define HORIZONTAL_FRONT_PORCH 2
#define VERTICAL_SYNCHRONOUS_PULSE 10
#define VERTICAL_BACK_PORCH 2
#define ACTIVE_HEIGHT 272
#define VERTICAL_FRONT_PORCH 2
#define LCD_WIGHT ACTIVE_WIDTH
#define LCD_HIGHT ACTIVE_HEIGHT
#define PIXEL_FORMAT LAYER_PPF_RGB565
#define PRE_PIXEL_BYTES 2
typedef struct _RGB_DATA
{
uint8_t Alpha;
uint8_t R;
uint8_t G;
uint8_t B;
} RGB;
extern RGB color_write;
extern RGB color_black;
extern RGB color_red;
extern RGB color_blue;
extern RGB color_green;
extern RGB color_yellow;
extern RGB color_cyan;
extern RGB color_magenta;
extern RGB color_orange;
extern RGB color_purple;
extern RGB color_gray;
extern RGB color_lightgray;
extern RGB color_darkgray;
extern RGB color_brown;
extern RGB color_pink;
extern RGB color_gold;
extern RGB color_silver;
void lcd_draw_picture(uint32_t picture_addr, uint32_t picture_width, uint32_t picture_height, uint32_t picture_x, uint32_t picture_y);
void lcd_draw_point(uint32_t point_x, uint32_t point_y, RGB *color);
uint32_t to_RGB565(RGB *color);
#endif // __DRV_LCD_H__

32
828ECO/drivers/include/drv_legacy.h

@ -0,0 +1,32 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-09-12 RTT the first version
*/
#ifndef DRIVERS_DRV_LEGACY_H_
#define DRIVERS_DRV_LEGACY_H_
#include <sys/types.h>
#include "rtdef.h"
#if RTTHREAD_VERSION <= 40101
#if defined(RT_USING_LIBC) && !defined(RT_USING_NANO)
typedef size_t rt_size_t; /**< Type for size number */
typedef ssize_t rt_ssize_t; /**< Used for a count of bytes or an error indication */
#else
typedef rt_base_t rt_ssize_t; /**< Used for a count of bytes or an error indication */
#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */
#else
#define RT_SECTION rt_section
#define RT_WEAK rt_weak
#define RT_USED rt_used
#ifndef ALIGN
#define ALIGN rt_align
#endif
#endif /* RTTHREAD_VERSION <= RT_VERSION_CHECK(4, 1, 1) */
#endif /* DRIVERS_DRV_LEGACY_H_ */

28
828ECO/drivers/include/drv_log.h

@ -0,0 +1,28 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-15 SummerGift first version
*/
/*
* NOTE: DO NOT include this file on the header file.
*/
#ifndef LOG_TAG
#define DBG_TAG "drv"
#else
#define DBG_TAG LOG_TAG
#endif /* LOG_TAG */
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* DRV_DEBUG */
#include <rtdbg.h>

45
828ECO/drivers/include/drv_pwm.h

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-11 kurisaw compatible with RT-Studio
*/
#ifndef __DRV_PWM_H__
#define __DRV_PWM_H__
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(RT_USING_PWM)
/* gd32 pwm driver class */
struct gd32_pwm
{
struct rt_device_pwm pwm_device;
uint32_t timer_periph;
char *name;
rcu_periph_enum timer_clk;
const char *pin_name;
rt_int16_t channel;
const char *alternate;
};
rt_err_t rt_hw_pwm_init(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __DRV_PWM_H__ */

297
828ECO/drivers/include/drv_sdio.h

@ -0,0 +1,297 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef __SDCARD_H_
#define __SDCARD_H_
#include <board.h>
#if defined(SOC_SERIES_GD32F10x)
#include "gd32f10x_sdio.h"
#include "gd32f10x_dma.h"
#elif defined(SOC_SERIES_GD32F20x)
#include "gd32f20x_sdio.h"
#include "gd32f20x_dma.h"
#elif defined(SOC_SERIES_GD32F30x)
#include "gd32f30x_sdio.h"
#include "gd32f30x_dma.h"
#elif defined(SOC_SERIES_GD32F4xx)
#include "gd32f4xx_sdio.h"
#include "gd32f4xx_dma.h"
#elif defined(SOC_SERIES_GD32H7xx)
#include "gd32h7xx_sdio.h"
#include "gd32h7xx_dma.h"
#endif
// #define USE_18V_SWITCH /* use SD Transceiver 1.8V mode */
#define SDIO_PERI_CLOCK RCU_SDIO0
#define SDIO_GPIO_CLK RCU_GPIOC
#define SDIO_GPIO_CMD RCU_GPIOD
#define SDIO_GPIO_D0 RCU_GPIOB
#define SDIO_GPIO_D1 RCU_GPIOC
#define SDIO_GPIO_D2 RCU_GPIOC
#define SDIO_GPIO_D3 RCU_GPIOC
#define SDIO_CLK_PORT GPIOC
#define SDIO_CLK_PIN GPIO_PIN_12
#define SDIO_CMD_PORT GPIOD
#define SDIO_CMD_PIN GPIO_PIN_2
#define SDIO_D0_PORT GPIOB
#define SDIO_D0_PIN GPIO_PIN_13
#define SDIO_D1_PORT GPIOC
#define SDIO_D1_PIN GPIO_PIN_9
#define SDIO_D2_PORT GPIOC
#define SDIO_D2_PIN GPIO_PIN_10
#define SDIO_D3_PORT GPIOC
#define SDIO_D3_PIN GPIO_PIN_11
/* SD memory card bus commands index */
#define SD_CMD_GO_IDLE_STATE ((uint8_t)0) /* CMD0, GO_IDLE_STATE */
#define SD_CMD_ALL_SEND_CID ((uint8_t)2) /* CMD2, ALL_SEND_CID */
#define SD_CMD_SEND_RELATIVE_ADDR ((uint8_t)3) /* CMD3, SEND_RELATIVE_ADDR */
#define SD_CMD_SET_DSR ((uint8_t)4) /* CMD4, SET_DSR */
#define SD_CMD_SWITCH_FUNC ((uint8_t)6) /* CMD6, SWITCH_FUNC */
#define SD_CMD_SELECT_DESELECT_CARD ((uint8_t)7) /* CMD7, SELECT_DESELECT_CARD */
#define SD_CMD_SEND_IF_COND ((uint8_t)8) /* CMD8, SEND_IF_COND */
#define SD_CMD_SEND_CSD ((uint8_t)9) /* CMD9, SEND_CSD */
#define SD_CMD_SEND_CID ((uint8_t)10) /* CMD10, SEND_CID */
#define SD_CMD_VOLATAGE_SWITCH ((uint8_t)11) /* CMD11, SD_CMD_VOLATAGE_SWITCH */
#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12) /* CMD12, STOP_TRANSMISSION */
#define SD_CMD_SEND_STATUS ((uint8_t)13) /* CMD13, SEND_STATUS */
#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15) /* CMD15, GO_INACTIVE_STATE */
#define SD_CMD_SET_BLOCKLEN ((uint8_t)16) /* CMD16, SET_BLOCKLEN */
#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /* CMD17, READ_SINGLE_BLOCK */
#define SD_CMD_READ_MULTIPLE_BLOCK ((uint8_t)18) /* CMD18, READ_MULTIPLE_BLOCK */
#define SD_SEND_TUNING_PATTERN ((uint8_t)19) /* CMD19, SEND_TUNING_PATTERN */
#define SD_CMD_WRITE_BLOCK ((uint8_t)24) /* CMD24, WRITE_BLOCK */
#define SD_CMD_WRITE_MULTIPLE_BLOCK ((uint8_t)25) /* CMD25, WRITE_MULTIPLE_BLOCK */
#define SD_CMD_PROG_CSD ((uint8_t)27) /* CMD27, PROG_CSD */
#define SD_CMD_SET_WRITE_PROT ((uint8_t)28) /* CMD28, SET_WRITE_PROT */
#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29) /* CMD29, CLR_WRITE_PROT */
#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30) /* CMD30, SEND_WRITE_PROT */
#define SD_CMD_ERASE_WR_BLK_START ((uint8_t)32) /* CMD32, ERASE_WR_BLK_START */
#define SD_CMD_ERASE_WR_BLK_END ((uint8_t)33) /* CMD33, ERASE_WR_BLK_END */
#define SD_CMD_ERASE ((uint8_t)38) /* CMD38, ERASE */
#define SD_CMD_LOCK_UNLOCK ((uint8_t)42) /* CMD42, LOCK_UNLOCK */
#define SD_CMD_APP_CMD ((uint8_t)55) /* CMD55, APP_CMD */
#define SD_CMD_GEN_CMD ((uint8_t)56) /* CMD56, GEN_CMD */
/* SD memory card application specific commands index */
#define SD_APPCMD_SET_BUS_WIDTH ((uint8_t)6) /* ACMD6, SET_BUS_WIDTH */
#define SD_APPCMD_SD_STATUS ((uint8_t)13) /* ACMD13, SD_STATUS */
#define SD_APPCMD_SEND_NUM_WR_BLOCKS ((uint8_t)22) /* ACMD22, SEND_NUM_WR_BLOCKS */
#define SD_APPCMD_SET_WR_BLK_ERASE_COUNT ((uint8_t)23) /* ACMD23, SET_WR_BLK_ERASE_COUNT */
#define SD_APPCMD_SD_SEND_OP_COND ((uint8_t)41) /* ACMD41, SD_SEND_OP_COND */
#define SD_APPCMD_SET_CLR_CARD_DETECT ((uint8_t)42) /* ACMD42, SET_CLR_CARD_DETECT */
#define SD_APPCMD_SEND_SCR ((uint8_t)51) /* ACMD51, SEND_SCR */
/* card command class */
#define SD_CCC_SWITCH BIT(10) /* class 10 */
#define SD_CCC_IO_MODE BIT(9) /* class 9 */
#define SD_CCC_APPLICATION_SPECIFIC BIT(8) /* class 8 */
#define SD_CCC_LOCK_CARD BIT(7) /* class 7 */
#define SD_CCC_WRITE_PROTECTION BIT(6) /* class 6 */
#define SD_CCC_ERASE BIT(5) /* class 5 */
#define SD_CCC_BLOCK_WRITE BIT(4) /* class 4 */
#define SD_CCC_BLOCK_READ BIT(2) /* class 2 */
#define SD_CCC_BASIC BIT(0) /* class 0 */
/* SD card data transmission mode */
#define SD_DMA_MODE ((uint32_t)0x00000000) /* DMA mode */
#define SD_POLLING_MODE ((uint32_t)0x00000001) /* polling mode */
/* lock unlock status */
#define SD_LOCK ((uint8_t)0x05) /* lock the SD card */
#define SD_UNLOCK ((uint8_t)0x02) /* unlock the SD card */
#define SD_SDSC ((uint32_t)0x00000000U) /*!< SD Standard Capacity <2G*/
#define SD_SDHC_SDXC ((uint32_t)0x00000001U) /*!< SD High Capacity <32G, SD Extended Capacity <2T */
#define SD_SPEED_DEFAULT ((uint32_t)0x00000000U) /*!< maintain current speed , clock frequency max value 25M*/
#define SD_SPEED_HIGH ((uint32_t)0x00000001U) /*!< switch high speed, clock frequency max value 50M */
#define SD_SPEED_SDR25 ((uint32_t)0x80FFFF01U) /*!< switch UHS-I SDR25 speed, clock frequency max value 50M */
#define SD_SPEED_SDR50 ((uint32_t)0x80FF1F02U) /*!< switch UHS-I SDR50 speed, clock frequency max value 104M */
#define SD_SPEED_SDR104 ((uint32_t)0x80FF1F03U) /*!< switch UHS-I SDR104 speed, clock frequency max value 208M */
#define SD_SPEED_DDR50 ((uint32_t)0x80FF1F04U) /*!< switch UHS-I DDR speed , clock frequency max value 50M */
/* supported memory cards types */
typedef enum
{
SDIO_STD_CAPACITY_SD_CARD_V1_1 = 0, /* standard capacity SD card version 1.1 */
SDIO_STD_CAPACITY_SD_CARD_V2_0, /* standard capacity SD card version 2.0 */
SDIO_STD_CAPACITY_SD_CARD_V3_0, /* standard capacity SD card version 3.0 */
SDIO_HIGH_CAPACITY_SD_CARD, /* high capacity SD card */
SDIO_SECURE_DIGITAL_IO_CARD, /* secure digital IO card */
SDIO_SECURE_DIGITAL_IO_COMBO_CARD, /* secure digital IO combo card */
SDIO_MULTIMEDIA_CARD, /* multimedia card */
SDIO_HIGH_CAPACITY_MULTIMEDIA_CARD, /* high capacity multimedia card */
SDIO_HIGH_SPEED_MULTIMEDIA_CARD /* high speed multimedia card */
} sdio_card_type_enum;
/* card identification (CID) register */
typedef struct
{
__IO uint8_t mid; /* manufacturer ID */
__IO uint16_t oid; /* OEM/application ID */
__IO uint32_t pnm0; /* product name */
__IO uint8_t pnm1; /* product name */
__IO uint8_t prv; /* product revision */
__IO uint32_t psn; /* product serial number */
__IO uint16_t mdt; /* manufacturing date */
__IO uint8_t cid_crc; /* CID CRC7 checksum */
} sd_cid_struct;
/* CSD register (CSD version 1.0 and 2.0) */
typedef struct
{
__IO uint8_t csd_struct; /* CSD struct */
__IO uint8_t taac; /* data read access-time */
__IO uint8_t nsac; /* data read access-time in CLK cycles */
__IO uint8_t tran_speed; /* max. data transfer rate */
__IO uint16_t ccc; /* card command classes */
__IO uint8_t read_bl_len; /* max. read data block length */
__IO uint8_t read_bl_partial; /* partial blocks for read allowed */
__IO uint8_t write_blk_misalign; /* write block misalignment */
__IO uint8_t read_blk_misalign; /* read block misalignment */
__IO uint8_t dsp_imp; /* DSR implemented */
__IO uint32_t c_size; /* device size, 12 bits in CSD version 1.0, 22 bits in CSD version 2.0 */
__IO uint8_t vdd_r_curr_min; /* max. read current @VDD min, CSD version 1.0 */
__IO uint8_t vdd_r_curr_max; /* max. read current @VDD max, CSD version 1.0 */
__IO uint8_t vdd_w_curr_min; /* max. write current @VDD min, CSD version 1.0 */
__IO uint8_t vdd_w_curr_max; /* max. write current @VDD max, CSD version 1.0 */
__IO uint8_t c_size_mult; /* device size multiplier, CSD version 1.0 */
__IO uint8_t erase_blk_en; /* erase single block enable */
__IO uint8_t sector_size; /* erase sector size */
__IO uint8_t wp_grp_size; /* write protect group size */
__IO uint8_t wp_grp_enable; /* write protect group enable */
__IO uint8_t r2w_factor; /* write speed factor */
__IO uint8_t write_bl_len; /* max. write data block length */
__IO uint8_t write_bl_partial; /* partial blocks for write allowed */
__IO uint8_t file_format_grp; /* file format group */
__IO uint8_t copy_flag; /* copy flag (OTP) */
__IO uint8_t perm_write_protect; /* permanent write protection */
__IO uint8_t tmp_write_protect; /* temporary write protection */
__IO uint8_t file_format; /* file format */
__IO uint8_t csd_crc; /* CSD CRC checksum */
} sd_csd_struct;
/* information of card */
typedef struct
{
sd_cid_struct card_cid; /* CID register */
sd_csd_struct card_csd; /* CSD register */
sdio_card_type_enum card_type; /* card tpye */
uint32_t card_capacity; /* card capacity */
uint32_t card_blocksize; /* card block size */
uint16_t card_rca; /* card relative card address */
} sd_card_info_struct;
/* SD error flags */
typedef enum
{
SD_OUT_OF_RANGE = 0, /* command's argument was out of range */
SD_ADDRESS_ERROR, /* misaligned address which did not match the block length */
SD_BLOCK_LEN_ERROR, /* transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */
SD_ERASE_SEQ_ERROR, /* an error in the sequence of erase command occurs */
SD_ERASE_PARAM, /* an invalid selection of write-blocks for erase occurred */
SD_WP_VIOLATION, /* attempt to program a write protect block or permanent write protected card */
SD_LOCK_UNLOCK_FAILED, /* sequence or password error has been detected in lock/unlock card command */
SD_COM_CRC_ERROR, /* CRC check of the previous command failed */
SD_ILLEGAL_COMMAND, /* command not legal for the card state */
SD_CARD_ECC_FAILED, /* card internal ECC was applied but failed to correct the data */
SD_CC_ERROR, /* internal card controller error */
SD_GENERAL_UNKNOWN_ERROR, /* general or unknown error occurred during the operation */
SD_CSD_OVERWRITE, /* read only section of the CSD does not match the card content or an attempt to reverse the copy or permanent WP bits was made */
SD_WP_ERASE_SKIP, /* only partial address space was erased or the temporary or permanent write protected card was erased */
SD_CARD_ECC_DISABLED, /* command has been executed without using internal ECC */
SD_ERASE_RESET, /* erase sequence was cleared before executing because an out of erase sequence command was received */
SD_AKE_SEQ_ERROR, /* error in the sequence of the authentication process */
SD_CMD_CRC_ERROR, /* command response received (CRC check failed) */
SD_DATA_CRC_ERROR, /* data block sent/received (CRC check failed) */
SD_CMD_RESP_TIMEOUT, /* command response timeout */
SD_DATA_TIMEOUT, /* data timeout */
SD_TX_UNDERRUN_ERROR, /* transmit FIFO underrun error occurs */
SD_RX_OVERRUN_ERROR, /* received FIFO overrun error occurs */
SD_START_BIT_ERROR, /* start bit error in the bus */
SD_VOLTRANGE_INVALID, /* the voltage range is invalid */
SD_PARAMETER_INVALID, /* the parameter is invalid */
SD_OPERATION_IMPROPER, /* the operation is improper */
SD_FUNCTION_UNSUPPORTED, /* the function is unsupported */
SD_ERROR, /* an error occurred */
SD_DMA_ERROR, /* an error when idma transfer */
SD_OK /* no error occurred */
} sd_error_enum;
typedef enum
{
SD_NO_TRANSFER = 0, /* no data transfer is acting */
SD_TRANSFER_IN_PROGRESS /* data transfer is in progress */
} sd_transfer_state_enum;
/* function declarations */
/* initialize the SD card and make it in standby state */
sd_error_enum sd_init(uint32_t SDIO);
/* initialize the card and get CID and CSD of the card */
sd_error_enum sd_card_init(uint32_t SDIO);
/* configure the clock and the work voltage, and get the card type */
sd_error_enum sd_power_on(uint32_t SDIO);
/* close the power of SDIO */
sd_error_enum sd_power_off(uint32_t SDIO);
/* configure the bus mode */
sd_error_enum sd_bus_mode_config(uint32_t SDIO, uint32_t busmode, uint32_t speed);
/* configure the mode of transmission */
sd_error_enum sd_transfer_mode_config(uint32_t txmode);
/* read a block data into a buffer from the specified address of a card */
sd_error_enum sd_block_read(uint32_t SDIO, uint32_t *preadbuffer, uint32_t readaddr, uint16_t blocksize);
/* read multiple blocks data into a buffer from the specified address of a card */
sd_error_enum sd_multiblocks_read(uint32_t SDIO, uint32_t *preadbuffer, uint32_t readaddr, uint16_t blocksize, uint32_t blocksnumber);
/* write a block data to the specified address of a card */
sd_error_enum sd_block_write(uint32_t SDIO, uint32_t *pwritebuffer, uint32_t writeaddr, uint16_t blocksize);
/* write multiple blocks data to the specified address of a card */
sd_error_enum sd_multiblocks_write(uint32_t SDIO, uint32_t *pwritebuffer, uint32_t writeaddr, uint16_t blocksize, uint32_t blocksnumber);
/* erase a continuous area of a card */
sd_error_enum sd_erase(uint32_t SDIO, uint32_t startaddr, uint32_t endaddr);
/* process all the interrupts which the corresponding flags are set */
sd_error_enum sd_interrupts_process(uint32_t SDIO);
/* select or deselect a card */
sd_error_enum sd_card_select_deselect(uint32_t SDIO, uint16_t cardrca);
/* get the card status whose response format R1 contains a 32-bit field */
sd_error_enum sd_cardstatus_get(uint32_t SDIO, uint32_t *pcardstatus);
/* get the SD status, the size of the SD status is one data block of 512 bit */
sd_error_enum sd_sdstatus_get(uint32_t SDIO, uint32_t *psdstatus);
/* stop an ongoing data transfer */
sd_error_enum sd_transfer_stop(uint32_t SDIO);
/* lock or unlock a card */
sd_error_enum sd_lock_unlock(uint32_t SDIO, uint8_t lockstate);
/* get the data transfer state */
sd_transfer_state_enum sd_transfer_state_get(uint32_t SDIO);
/* get SD card capacity(KB) */
uint32_t sd_card_capacity_get(uint32_t SDIO);
/* get the detailed information of the SD card based on received CID and CSD */
sd_error_enum sd_card_information_get(uint32_t SDIO, sd_card_info_struct *pcardinfo);
/* switch 1.8V power level of SD card */
sd_error_enum sd_card_voltage_switch(uint32_t SDIO);
#ifdef USE_18V_SWITCH
/* configure CPDM */
void cpdm_config(void);
/* perform sampling point tuning using tuning command */
sd_error_enum sd_tuning(uint32_t SDIO);
#endif /* USE_18V_SWITCH */
#endif /* __SDCARD_H_ */

81
828ECO/drivers/include/drv_spi.h

@ -0,0 +1,81 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-12-20 BruceOu first implementation
* 2025-10-10 WangShun compatible with RT-Studio
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#define RT_SPI_USING_DMA
#if !defined(SOC_SERIES_GD32H7xx) && !defined(SOC_SERIES_GD32H75E)
#undef RT_SPI_USING_DMA
#endif
struct gd32_spi_cs
{
uint32_t GPIOx;
uint32_t GPIO_Pin;
};
#ifdef RT_SPI_USING_DMA
typedef struct
{
/* dma peripheral */
uint32_t dma_periph;
/* dma txchannel */
dma_channel_enum txdma_ch;
/* dma rxchannel */
dma_channel_enum rxdma_ch;
/* tx dma request */
uint32_t dma_mux_req_tx;
/* rx dma request */
uint32_t dma_mux_req_rx;
/* dma flag */
uint32_t rx_flag;
/* setting receive len */
rt_size_t setting_recv_len;
} gd32_spi_dma;
#endif
/* gd32 spi dirver class */
struct gd32_spi
{
uint32_t spi_periph;
char *bus_name;
rcu_periph_enum spi_clk;
struct rt_spi_bus *spi_bus;
const char *sck_pin_name; /* sck pin name */
const char *miso_pin_name; /* miso pin name */
const char *mosi_pin_name; /* mosi pin name */
const char *alternate; /* afio mode */
#ifdef RT_SPI_USING_DMA
gd32_spi_dma *spi_dma;
#endif
};
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin);
#ifdef __cplusplus
}
#endif
#endif /* __DRV_SPI_H__ */

82
828ECO/drivers/include/drv_usart.h

@ -0,0 +1,82 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-20 BruceOu first implementation
* 2025-10-09 WangShun compatible with RT-Studio
*/
#ifndef __DRV_USART_H__
#define __DRV_USART_H__
#include <rthw.h>
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(SOC_SERIES_GD32H7xx) || !defined(SOC_SERIES_GD32H75E)
#undef RT_SERIAL_USING_DMA
#endif
#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n))
#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n))
#ifdef RT_SERIAL_USING_DMA
typedef struct
{
/* dma peripheral */
uint32_t dma_periph;
/* dma channel */
dma_channel_enum dma_ch;
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
/* rx dma request */
uint32_t dma_mux_req_rx;
#endif
/* dma flag */
uint32_t rx_flag;
/* dma irq channel */
uint8_t rx_irq_ch;
/* setting receive len */
rt_size_t setting_recv_len;
/* last receive index */
rt_size_t last_recv_index;
} gd32_uart_dma;
#endif
/* GD32 uart driver */
struct gd32_uart
{
uint32_t uart_periph; /* Instance */
IRQn_Type irqn; /* irqn */
rcu_periph_enum per_clk; /* uart_clk */
const char *tx_pin_name; /* tx pin name */
const char *rx_pin_name; /* rx pin name */
const char *alternate; /* rx pin name */
#ifdef RT_SERIAL_USING_DMA
gd32_uart_dma *uart_dma;
#ifdef RT_SERIAL_USING_TX_DMA
gd32_uart_dma *uart_tx_dma;
#endif
#endif
struct rt_serial_device * serial; /* serial device */
char *device_name;
};
int rt_hw_usart_init(void);
#ifdef __cplusplus
}
#endif
#endif /* __DRV_USART_H__ */

1285
828ECO/drivers/include/synopsys_emac.h

File diff suppressed because it is too large

29
828ECO/drivers/include/usb/drv_otghs_dev.h

@ -0,0 +1,29 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef __DRV_OTGFS_DEV_H__
#define __DRV_OTGFS_DEV_H__
#include <rtthread.h>
#include "drv_usb_dev.h"
void usbd_reset_callback(void);
void usbd_setup_stage_callback(struct urequest *setup_packet);
void usbd_data_in_stage_callback(uint8_t epnum, uint16_t data_count);
void usbd_data_out_stage_callback(uint8_t epnum, uint16_t data_count);
void usbd_set_connection_state(uint8_t state);
int gd_usbd_register(void);
#endif

34
828ECO/drivers/include/usb/drv_otghs_host.h

@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef __DRV_OTGFS_HOST_H__
#define __DRV_OTGFS_HOST_H__
#include <rtthread.h>
#include "drv_usb_host.h"
#include "drv_usbh_transc.h"
#include "drv_usbh_pipe.h"
#define OTG_FS_PORT 1
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
void usbh_connect_callback(usb_core_driver *hhcd);
void usbh_disconnect_callback(usb_core_driver *hhcd);
void usbh_hc_notifyurbchange_callback(usb_core_driver *hhcd, uint8_t chnum, usb_urb_state urb_state);
int gd_usbh_register(void);
#endif /* BSP_USING_USB && RT_USING_USB_HOST */
#endif

369
828ECO/drivers/include/usb/drv_usb_core.h

@ -0,0 +1,369 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef DRV_USB_CORE_H
#define DRV_USB_CORE_H
#include "drv_usb_regs.h"
#define USB_FS_EP0_MAX_LEN 64U /*!< maximum packet size of endpoint 0 */
#define HC_MAX_PACKET_COUNT 140U /*!< maximum packet count */
#define EP_ID(x) ((uint8_t)((x) & 0x7FU)) /*!< endpoint number */
#define EP_DIR(x) ((uint8_t)((x) >> 7)) /*!< endpoint direction */
typedef struct urequest usb_req;
enum _usb_eptype
{
USB_EPTYPE_CTRL = 0U, /*!< control endpoint type */
USB_EPTYPE_ISOC = 1U, /*!< isochronous endpoint type */
USB_EPTYPE_BULK = 2U, /*!< bulk endpoint type */
USB_EPTYPE_INTR = 3U, /*!< interrupt endpoint type */
USB_EPTYPE_MASK = 3U /*!< endpoint type mask */
};
typedef enum
{
USB_OTG_OK = 0U, /*!< USB OTG status OK */
USB_OTG_FAIL /*!< USB OTG status fail */
} usb_otg_status;
typedef enum
{
USB_OK = 0U, /*!< USB status OK */
USB_FAIL /*!< USB status fail */
} usb_status;
typedef enum
{
USB_USE_FIFO, /*!< USB use FIFO transfer mode */
USB_USE_DMA /*!< USB use DMA transfer mode */
} usb_transfer_mode;
typedef enum
{
LPM_L0 = 0U, /*!< on */
LPM_L1, /*!< LPM L1 sleep */
LPM_L2, /*!< suspend */
LPM_L3, /*!< off */
} usb_lpm_state;
enum usb_ctl_status
{
USB_CTL_IDLE = 0U, /*!< USB control transfer idle state */
USB_CTL_DATA_IN, /*!< USB control transfer data IN state */
USB_CTL_LAST_DATA_IN, /*!< USB control transfer last data IN state */
USB_CTL_DATA_OUT, /*!< USB control transfer data OUT state */
USB_CTL_LAST_DATA_OUT, /*!< USB control transfer last data OUT state */
USB_CTL_STATUS_IN, /*!< USB control transfer status IN state*/
USB_CTL_STATUS_OUT /*!< USB control transfer status OUT state */
};
typedef enum
{
LPM_L0_ACTIVE = 0U, /*!< on */
LPM_L1_ACTIVE, /*!< LPM L1 sleep */
} usb_lpm_type;
typedef struct
{
uint8_t core_enum; /*!< USB core type */
uint8_t core_speed; /*!< USB core speed */
uint8_t num_pipe; /*!< USB host channel numbers */
uint8_t num_ep; /*!< USB device endpoint numbers */
uint8_t transfer_mode; /*!< USB transfer mode */
uint8_t phy_itf; /*!< USB core PHY interface */
uint8_t sof_enable; /*!< USB SOF output */
uint8_t low_power; /*!< USB low power */
uint8_t lpm_enable; /*!< USB link power mode(LPM) */
uint8_t vbus_sensing_enable; /*!< USB VBUS sensing feature */
uint8_t use_dedicated_ep1; /*!< USB dedicated endpoint1 interrupt */
uint8_t use_external_vbus; /*!< enable or disable the use of the external VBUS */
uint32_t base_reg; /*!< base register address */
} usb_core_basic;
#ifdef USE_DEVICE_MODE
/* USB descriptor */
typedef struct _usb_desc
{
uint8_t *dev_desc; /*!< device descriptor */
uint8_t *config_desc; /*!< configuration descriptor */
uint8_t *bos_desc; /*!< BOS descriptor */
#ifdef USE_USB_HS
uint8_t *other_speed_config_desc; /*!< other speed configuration descriptor */
uint8_t *qualifier_desc; /*!< qualifier descriptor */
#endif
void * const *strings; /*!< string descriptor */
} usb_desc;
/* USB power management */
typedef struct _usb_pm
{
uint8_t power_mode; /*!< power mode */
uint8_t power_low; /*!< power low */
uint8_t dev_remote_wakeup; /*!< remote wakeup */
uint8_t remote_wakeup_on; /*!< remote wakeup on */
usb_lpm_state lpm_state; /*!< LPM state */
uint32_t BESL; /*!< BESL value */
} usb_pm;
/* USB control information */
typedef struct _usb_control
{
usb_req req; /*!< USB standard device request */
uint8_t ctl_state; /*!< USB control transfer state */
uint8_t ctl_zlp; /*!< zero length package */
} usb_control;
typedef struct
{
struct
{
uint8_t num : 4U; /*!< the endpoint number.it can be from 0 to 6 */
uint8_t pad : 3U; /*!< padding between number and direction */
uint8_t dir : 1U; /*!< the endpoint direction */
} ep_addr;
uint8_t ep_type; /*!< USB endpoint type */
uint8_t ep_stall; /*!< USB endpoint STALL status */
uint8_t frame_num; /*!< number of frame */
uint16_t max_len; /*!< maximum packet length */
/* transaction level variables */
uint8_t *xfer_buf; /*!< transmit buffer */
uint32_t xfer_len; /*!< transmit buffer length */
uint32_t xfer_count; /*!< transmit buffer count */
uint32_t remain_len; /*!< remain packet length */
uint32_t dma_addr; /*!< DMA address */
} usb_transc;
typedef struct _usb_core_driver usb_dev;
typedef struct _usb_class_core
{
uint8_t alter_set; /*!< alternative set */
uint8_t command; /*!< device class request command */
uint8_t (*init)(usb_dev *udev, uint8_t config_index); /*!< initialize handler */
uint8_t (*deinit)(usb_dev *udev, uint8_t config_index); /*!< de-initialize handler */
uint8_t (*req_proc)(usb_dev *udev, usb_req *req); /*!< device request handler */
uint8_t (*set_intf)(usb_dev *udev, usb_req *req); /*!< device set interface callback */
uint8_t (*ctlx_in)(usb_dev *udev); /*!< device control IN callback */
uint8_t (*ctlx_out)(usb_dev *udev); /*!< device control OUT callback */
uint8_t (*data_in)(usb_dev *udev, uint8_t ep_num); /*!< device data IN handler */
uint8_t (*data_out)(usb_dev *udev, uint8_t ep_num); /*!< device data OUT handler */
uint8_t (*SOF)(usb_dev *udev); /*!< start of frame handler */
uint8_t (*incomplete_isoc_in)(usb_dev *udev); /*!< incomplete synchronization IN transfer handler */
uint8_t (*incomplete_isoc_out)(usb_dev *udev); /*!< incomplete synchronization OUT transfer handler */
} usb_class_core;
typedef struct _usb_perp_dev
{
uint8_t config; /*!< configuration */
uint8_t dev_addr; /*!< device address */
__IO uint8_t cur_status; /*!< current status */
__IO uint8_t backup_status; /*!< backup status */
usb_transc transc_in[USBHS_MAX_TX_FIFOS]; /*!< endpoint IN transaction */
usb_transc transc_out[USBHS_MAX_TX_FIFOS]; /*!< endpoint OUT transaction */
usb_pm pm; /*!< power management */
usb_control control; /*!< USB control information */
usb_desc *desc; /*!< USB descriptors pointer */
usb_class_core *class_core; /*!< class driver */
void *class_data[4]; /*!< class data pointer */
void *user_data; /*!< user data pointer */
void *pdata; /*!< reserved data pointer */
} usb_perp_dev;
#endif /* USE_DEVICE_MODE */
#ifdef USE_HOST_MODE
typedef enum _usb_pipe_status
{
PIPE_IDLE = 0U, /*!< host pipe IDLE status */
PIPE_XF, /*!< host pipe transfer completed status */
PIPE_HALTED, /*!< host pipe halted status */
PIPE_NAK, /*!< host pipe NAK status */
PIPE_NYET, /*!< host pipe NYET status */
PIPE_STALL, /*!< host pipe STALL status */
PIPE_TRACERR, /*!< host pipe transaction error status */
PIPE_BBERR, /*!< host pipe babble error status */
PIPE_REQOVR, /*!< host pipe frame overrun status */
PIPE_DTGERR, /*!< host pipe data toggle error status */
} usb_pipe_status;
typedef enum _usb_pipe_mode
{
PIPE_PERIOD = 0U, /*!< USB host pipe PERIOD mode */
PIPE_NON_PERIOD = 1U /*!< USB host pipe NOT PERIOD mode */
} usb_pipe_mode;
typedef enum _usb_urb_state
{
URB_IDLE = 0U, /*!< USB URB IDLE state */
URB_DONE, /*!< USB URB DONE state */
URB_NOTREADY, /*!< USB URB NOT READY state */
URB_ERROR, /*!< USB URB ERROR state */
URB_STALL, /*!< USB URB STALL state */
URB_PING /*!< USB URB PING state */
} usb_urb_state;
typedef struct _usb_pipe
{
uint8_t in_used; /*!< pipe used */
uint8_t dev_addr; /*!< USB device address */
uint32_t dev_speed; /*!< USB device speed */
struct
{
uint8_t num; /*!< endpoint numbers */
uint8_t dir; /*!< endpoint direction */
uint8_t type; /*!< endpoint transfer type */
uint16_t mps; /*!< endpoint max packet size */
} ep;
__IO uint8_t supp_ping; /*!< host pipe support PING */
__IO uint8_t do_ping; /*!< host pipe do PING */
__IO uint32_t DPID; /*!< data PID */
uint8_t *xfer_buf; /*!< USB transfer buffer */
uint32_t xfer_len; /*!< USB transfer length */
uint32_t xfer_count; /*!< USB transfer count */
uint8_t data_toggle_in; /*!< toggle DATA IN */
uint8_t data_toggle_out; /*!< toggle DATA OUT */
__IO uint32_t err_count; /*!< error count */
__IO usb_pipe_status pp_status; /*!< USB pipe status */
__IO usb_urb_state urb_state; /*!< USB URB state */
} usb_pipe;
typedef struct _usb_host_drv
{
__IO uint32_t connect_status; /*!< connect status */
__IO uint32_t port_enabled; /*!< USB port enable */
__IO uint32_t backup_xfercount[USBHS_MAX_TX_FIFOS]; /*!< USB backup transfer data count */
usb_pipe pipe[USBHS_MAX_TX_FIFOS]; /*!< USB host pipe handles */
void *data; /*!< user data pointer */
} usb_host_drv;
#endif /* USE_HOST_MODE */
typedef struct _usb_core_driver
{
usb_core_basic bp; /*!< USB basic parameters */
usb_core_regs regs; /*!< USB registers */
#ifdef USE_DEVICE_MODE
usb_perp_dev dev; /*!< USB peripheral device */
#endif /* USE_DEVICE_MODE */
#ifdef USE_HOST_MODE
usb_host_drv host; /*!< USB peripheral host */
#endif /* USE_HOST_MODE */
} usb_core_driver;
typedef enum
{
BCD_NONE = 0,
BCD_SDP,
BCD_DCP,
BCD_CDP,
BCD_PS2,
BCD_ERROR
} bcd_type;
/* static inline function definitions */
/*!
\brief get the global interrupts
\param[in] usb_regs: pointer to USB core registers
\param[out] none
\retval interrupt status
*/
__STATIC_INLINE uint32_t usb_coreintr_get(usb_core_regs *usb_regs)
{
uint32_t reg_data = usb_regs->gr->GINTEN;
reg_data &= usb_regs->gr->GINTF;
return reg_data;
}
/*!
\brief set USB RX FIFO size
\param[in] usb_regs: pointer to USB core registers
\param[in] size: assigned FIFO size
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_set_rxfifo(usb_core_regs *usb_regs, uint16_t size)
{
usb_regs->gr->GRFLEN = size;
}
/*!
\brief enable the global interrupts
\param[in] usb_regs: pointer to USB core registers
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_globalint_enable(usb_core_regs *usb_regs)
{
/* enable USB global interrupt */
usb_regs->gr->GAHBCS |= GAHBCS_GINTEN;
}
/*!
\brief disable the global interrupts
\param[in] usb_regs: pointer to USB core registers
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_globalint_disable(usb_core_regs *usb_regs)
{
/* disable USB global interrupt */
usb_regs->gr->GAHBCS &= ~GAHBCS_GINTEN;
}
/* function declarations */
/* configures USB parameters */
void usb_para_init(usb_core_driver *core, uint32_t usb_periph, uint32_t usb_speed);
/* configure core capabilities */
usb_status usb_basic_init(usb_core_basic *usb_basic, usb_core_regs *usb_regs);
/*initializes the USB controller registers and prepares the core device mode or host mode operation*/
usb_status usb_core_init(usb_core_basic usb_basic, usb_core_regs *usb_regs);
/* write a packet into the TX FIFO associated with the endpoint */
usb_status usb_txfifo_write(usb_core_regs *usb_regs, uint8_t *src_buf, uint8_t fifo_num, uint16_t byte_count);
/* read a packet from the RX FIFO associated with the endpoint */
void *usb_rxfifo_read(usb_core_regs *usb_regs, uint8_t *dest_buf, uint16_t byte_count);
/* flush a TX FIFO or all TX FIFOs */
usb_status usb_txfifo_flush(usb_core_regs *usb_regs, uint8_t fifo_num);
/* flush the entire RX FIFO */
usb_status usb_rxfifo_flush(usb_core_regs *usb_regs);
/* set endpoint or channel TX FIFO size */
void usb_set_txfifo(usb_core_regs *usb_regs, uint8_t fifo, uint16_t size);
/* set USB current mode */
void usb_curmode_set(usb_core_regs *usb_regs, uint8_t mode);
void usb_clock_active(usb_core_driver *udev);
#endif /* DRV_USB_CORE_H */

195
828ECO/drivers/include/usb/drv_usb_dev.h

@ -0,0 +1,195 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef DRV_USB_DEV_H
#define DRV_USB_DEV_H
#include "drv_usb_core.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE)
#define EP_IN(x) ((uint8_t)(0x80U | (x))) /*!< device IN endpoint */
#define EP_OUT(x) ((uint8_t)(x)) /*!< device OUT endpoint */
#define EP_MAX_PACKET_SIZE_MASK 0x07FFU /*!< endpoint maximum packet size mask */
#define USB_MIN(a, b) (((a) < (b)) ? (a) : (b))
/* static inline function definitions */
/*!
\brief configure the USB device to be disconnected
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_dev_disconnect(usb_core_driver *udev)
{
udev->regs.dr->DCTL |= DCTL_SD;
}
/*!
\brief configure the USB device to be connected
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_dev_connect(usb_core_driver *udev)
{
udev->regs.dr->DCTL &= ~DCTL_SD;
}
/*!
\brief set the USB device address
\param[in] udev: pointer to USB device
\param[in] dev_addr: device address for setting
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_devaddr_set(usb_core_driver *udev, uint8_t dev_addr)
{
udev->regs.dr->DCFG &= ~DCFG_DAR;
udev->regs.dr->DCFG |= (uint32_t)dev_addr << 4;
}
/*!
\brief read device all OUT endpoint interrupt register
\param[in] udev: pointer to USB device
\param[out] none
\retval interrupt status
*/
__STATIC_INLINE uint32_t usb_oepintnum_read(usb_core_driver *udev)
{
uint32_t value = udev->regs.dr->DAEPINT;
value &= udev->regs.dr->DAEPINTEN;
return (value & DAEPINT_OEPITB) >> 16;
}
/*!
\brief read device OUT endpoint interrupt flag register
\param[in] udev: pointer to USB device
\param[in] ep_num: endpoint number
\param[out] none
\retval interrupt status
*/
__STATIC_INLINE uint32_t usb_oepintr_read(usb_core_driver *udev, uint8_t ep_num)
{
uint32_t value = udev->regs.er_out[ep_num]->DOEPINTF;
value &= udev->regs.dr->DOEPINTEN;
return value;
}
/*!
\brief read device all IN endpoint interrupt register
\param[in] udev: pointer to USB device
\param[out] none
\retval interrupt status
*/
__STATIC_INLINE uint32_t usb_iepintnum_read(usb_core_driver *udev)
{
uint32_t value = udev->regs.dr->DAEPINT;
value &= udev->regs.dr->DAEPINTEN;
return value & DAEPINT_IEPITB;
}
/*!
\brief set remote wakeup signaling
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_rwkup_set(usb_core_driver *udev)
{
if (udev->dev.pm.dev_remote_wakeup)
{
/* enable remote wakeup signaling */
udev->regs.dr->DCTL |= DCTL_RWKUP;
}
}
/*!
\brief reset remote wakeup signaling
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_rwkup_reset(usb_core_driver *udev)
{
if (udev->dev.pm.dev_remote_wakeup)
{
/* disable remote wakeup signaling */
udev->regs.dr->DCTL &= ~DCTL_RWKUP;
}
}
/*!
\brief enable USB BCD function
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_bcd_enable(usb_core_driver *udev)
{
udev->regs.gr->GCCFG |= GCCFG_BCDEN;
}
/*!
\brief disable USB BCD function
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_bcd_disable(usb_core_driver *udev)
{
udev->regs.gr->GCCFG &= ~GCCFG_BCDEN;
}
/* function declarations */
/* initialize USB core registers for device mode */
usb_status usb_devcore_init(usb_core_driver *udev);
/* enable the USB device mode interrupts */
usb_status usb_devint_enable(usb_core_driver *udev);
/* active the USB endpoint 0 transaction */
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc);
/* active the USB transaction */
usb_status usb_ep_active(usb_core_driver *udev, uint8_t ep_addr, uint8_t ep_mps, uint8_t ep_attr);
/* deactivate the USB transaction */
usb_status usb_ep_deactivate(usb_core_driver *udev, uint8_t ep_addr);
/* configure USB transaction to start IN transfer */
usb_status usb_ep_inxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count);
/* configure USB transaction to start OUT transfer */
usb_status usb_ep_outxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count);
/* set the USB transaction STALL status */
usb_status usb_ep_stall(usb_core_driver *udev, uint8_t ep_addr);
/* clear the USB transaction STALL status */
usb_status usb_ep_clrstall(usb_core_driver *udev, uint8_t ep_addr);
/* read device IN endpoint interrupt flag register */
uint32_t usb_iepintr_read(usb_core_driver *udev, uint8_t ep_num);
/* configures OUT endpoint 0 to receive SETUP packets */
void usb_ctlep_startout(usb_core_driver *udev);
/* active remote wakeup signaling */
void usb_rwkup_active(usb_core_driver *udev);
/* active USB core clock */
void usb_clock_active(usb_core_driver *udev);
/* USB device suspend */
void usb_dev_suspend(usb_core_driver *udev);
/* stop the device and clean up FIFOs */
void usb_dev_stop(usb_core_driver *udev);
/* USB battery charging detect operation */
bcd_type usbd_bcd_detect(usb_core_driver *udev);
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */
#endif /* DRV_USB_DEV_H */

93
828ECO/drivers/include/usb/drv_usb_host.h

@ -0,0 +1,93 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef DRV_USB_HOST_H
#define DRV_USB_HOST_H
#include "drv_usb_core.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
typedef enum
{
USBH_OK = 0U,
USBH_BUSY,
USBH_FAIL,
USBH_NOT_SUPPORTED,
USBH_UNRECOVERED_ERROR,
USBH_SPEED_UNKNOWN_ERROR,
USBH_APPLY_DEINIT
} usbh_status;
/*!
\brief get USB even frame
\param[in] udev: pointer to USB device
\param[out] none
\retval USB even frame state
*/
__STATIC_INLINE uint8_t usb_frame_even(usb_core_driver *udev)
{
return (uint8_t) !(udev->regs.hr->HFINFR & 0x01U);
}
/*!
\brief read USB port
\param[in] udev: pointer to USB device
\param[out] none
\retval port status
*/
__STATIC_INLINE uint32_t usb_port_read(usb_core_driver *udev)
{
return *udev->regs.HPCS & ~(HPCS_PE | HPCS_PCD | HPCS_PEDC);
}
/*!
\brief get USB current speed
\param[in] udev: pointer to USB device
\param[out] none
\retval USB current speed
*/
__STATIC_INLINE uint32_t usb_curspeed_get(usb_core_driver *udev)
{
return *udev->regs.HPCS & HPCS_PS;
}
/*!
\brief get USB current frame
\param[in] udev: pointer to USB device
\param[out] none
\retval USB current frame
*/
__STATIC_INLINE uint32_t usb_curframe_get(usb_core_driver *udev)
{
return (udev->regs.hr->HFINFR & 0xFFFFU);
}
/* function declarations */
/* initializes USB core for host mode */
usb_status usb_host_init(usb_core_driver *udev);
/* control the VBUS to power */
void usb_portvbus_switch(usb_core_driver *udev, uint8_t state);
/* reset host port */
uint32_t usb_port_reset(usb_core_driver *udev);
/* initialize host pipe */
usb_status usb_pipe_init(usb_core_driver *udev, uint8_t pipe_num);
/* prepare host pipe for transferring packets */
usb_status usb_pipe_xfer(usb_core_driver *udev, uint8_t pipe_num);
/* halt host pipe */
usb_status usb_pipe_halt(usb_core_driver *udev, uint8_t pipe_num);
/* configure host pipe to do ping operation */
usb_status usb_pipe_ping(usb_core_driver *udev, uint8_t pipe_num);
/* stop the USB host and clean up FIFO */
void usb_host_stop(usb_core_driver *udev);
#endif /* BSP_USING_USB && RT_USING_USB_HOST */
#endif /* DRV_USB_HOST_H */

42
828ECO/drivers/include/usb/drv_usb_hw.h

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef DRV_USB_HW_H
#define DRV_USB_HW_H
#include "drv_usb_core.h"
/* function declarations */
/* configure USB clock */
void usb_rcu_config(void);
/* configure USB data line GPIO */
void usb_gpio_config(void);
/* configure USB interrupt */
void usb_intr_config(void);
/* initializes delay unit using Timer2 */
void usb_timer_init(void);
/* delay in microseconds */
void usb_udelay(const uint32_t usec);
/* delay in milliseconds */
void usb_mdelay(const uint32_t msec);
/* configure USB clock */
void pllusb_rcu_config(uint32_t usb_periph);
#ifdef USE_HOST_MODE
/* configure systick */
void systick_config(void);
/* configure USB VBus */
void usb_vbus_config(void);
/* drive USB VBus */
void usb_vbus_drive(uint8_t State);
#endif /* USE_HOST_MODE */
#endif /* DRV_USB_HW_H */

728
828ECO/drivers/include/usb/drv_usb_regs.h

@ -0,0 +1,728 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef DRV_USB_REGS_H
#define DRV_USB_REGS_H
#include "usb_conf.h"
#define USBHS0 USBHS_BASE
#define USBHS1 (USBHS_BASE + 0x00040000U)
#define USBHS0_REG_BASE USBHS0 /*!< base address of USBHS0 registers */
#define USBHS1_REG_BASE USBHS1 /*!< base address of USBHS1 registers */
/* register definition */
#define USBHS_MAX_TX_FIFOS 16U /*!< FIFO number */
typedef struct
{
__IO uint32_t GOTGCS; /*!< USB global OTG control and status register 000h */
__IO uint32_t GOTGINTF; /*!< USB global OTG interrupt flag register 004h */
__IO uint32_t GAHBCS; /*!< USB global AHB control and status register 008h */
__IO uint32_t GUSBCS; /*!< USB global USB control and status register 00Ch */
__IO uint32_t GRSTCTL; /*!< USB global reset control register 010h */
__IO uint32_t GINTF; /*!< USB global interrupt flag register 014h */
__IO uint32_t GINTEN; /*!< USB global interrupt enable register 018h */
__IO uint32_t GRSTATR; /*!< USB receive status debug read register 01Ch */
__IO uint32_t GRSTATP; /*!< USB receive status and pop register 020h */
__IO uint32_t GRFLEN; /*!< USB global receive FIFO length register 024h */
__IO uint32_t DIEP0TFLEN_HNPTFLEN; /*!< USB device IN endpoint 0/host non-periodic transmit FIFO length register 028h */
__IO uint32_t HNPTFQSTAT; /*!< USB host non-periodic FIFO/queue status register 02Ch */
uint32_t Reserved30[2]; /*!< Reserved 030h */
__IO uint32_t GCCFG; /*!< USB global core configuration register 038h */
__IO uint32_t CID; /*!< USB core ID register 03Ch */
uint32_t Reserved40[5]; /*!< Reserved 040h-053h */
__IO uint32_t GLPMCFG; /*!< LPM configuration register 54h */
__IO uint32_t PWRD; /*!< power down register 58h */
uint32_t Reserved5C; /*!< Reserved 5Ch */
__IO uint32_t ADPCTL; /*!< ADP control and status register 60h */
uint32_t Reserved64[3]; /*!< Reserved 64h-6Fh */
__IO uint32_t PHYCTL; /*!< USBHS PHY control register 70h */
uint32_t Reserved74[35]; /*!< Reserved 74h-FFh */
__IO uint32_t HPTFLEN; /*!< USB host periodic transmit FIFO length register 100h */
__IO uint32_t DIEPTFLEN[15]; /*!< USB device IN endpoint transmit FIFO length register 104h */
} usb_gr;
typedef struct
{
__IO uint32_t HCTL; /*!< USB host control register 400h */
__IO uint32_t HFT; /*!< USB host frame interval register 404h */
__IO uint32_t HFINFR; /*!< USB host frame information remaining register 408h */
uint32_t Reserved40C; /*!< Reserved 40Ch */
__IO uint32_t HPTFQSTAT; /*!< USB host periodic transmit FIFO/queue status register 410h */
__IO uint32_t HACHINT; /*!< USB host all channels interrupt register 414h */
__IO uint32_t HACHINTEN; /*!< USB host all channels interrupt enable register 418h */
} usb_hr;
typedef struct
{
__IO uint32_t HCHCTL; /*!< USB host channel control register 500h */
__IO uint32_t HCHSTCTL; /*!< Reserved 504h */
__IO uint32_t HCHINTF; /*!< USB host channel interrupt flag register 508h */
__IO uint32_t HCHINTEN; /*!< USB host channel interrupt enable register 50Ch */
__IO uint32_t HCHLEN; /*!< USB host channel transfer length register 510h */
__IO uint32_t HCHDMAADDR; /*!< USB host channel-x DMA address register 514h*/
uint32_t Reserved[2];
} usb_pr;
typedef struct
{
__IO uint32_t DCFG; /*!< USB device configuration register 800h */
__IO uint32_t DCTL; /*!< USB device control register 804h */
__IO uint32_t DSTAT; /*!< USB device status register 808h */
uint32_t Reserved0C; /*!< Reserved 80Ch */
__IO uint32_t DIEPINTEN; /*!< USB device IN endpoint common interrupt enable register 810h */
__IO uint32_t DOEPINTEN; /*!< USB device OUT endpoint common interrupt enable register 814h */
__IO uint32_t DAEPINT; /*!< USB device all endpoints interrupt register 818h */
__IO uint32_t DAEPINTEN; /*!< USB device all endpoints interrupt enable register 81Ch */
uint32_t Reserved20; /*!< Reserved 820h */
uint32_t Reserved24; /*!< Reserved 824h */
__IO uint32_t DVBUSDT; /*!< USB device VBUS discharge time register 828h */
__IO uint32_t DVBUSPT; /*!< USB device VBUS pulsing time register 82Ch */
uint32_t Reserved30; /*!< Reserved 830h */
__IO uint32_t DIEPFEINTEN; /*!< USB Device IN endpoint FIFO empty interrupt enable register 834h */
__IO uint32_t DEP1INT; /*!< USB device endpoint 1 interrupt register 838h */
__IO uint32_t DEP1INTEN; /*!< USB device endpoint 1 interrupt enable register 83Ch */
uint32_t Reserved40; /*!< Reserved 840h */
__IO uint32_t DIEP1INTEN; /*!< USB device IN endpoint-1 interrupt enable register 844h */
uint32_t Reserved48[15]; /*!< Reserved 848-880h */
__IO uint32_t DOEP1INTEN; /*!< USB device OUT endpoint-1 interrupt enable register 884h */
} usb_dr;
typedef struct
{
__IO uint32_t DIEPCTL; /*!< USB device IN endpoint control register 900h + (EpNum * 20h) + 00h */
uint32_t Reserved04; /*!< Reserved 900h + (EpNum * 20h) + 04h */
__IO uint32_t DIEPINTF; /*!< USB device IN endpoint interrupt flag register 900h + (EpNum * 20h) + 08h */
uint32_t Reserved0C; /*!< Reserved 900h + (EpNum * 20h) + 0Ch */
__IO uint32_t DIEPLEN; /*!< USB device IN endpoint transfer length register 900h + (EpNum * 20h) + 10h */
__IO uint32_t DIEPDMAADDR; /*!< Device IN endpoint-x DMA address register 900h + (EpNum * 20h) + 14h */
__IO uint32_t DIEPTFSTAT; /*!< USB device IN endpoint transmit FIFO status register 900h + (EpNum * 20h) + 18h */
} usb_erin;
typedef struct
{
__IO uint32_t DOEPCTL; /*!< USB device IN endpoint control register B00h + (EpNum * 20h) + 00h */
uint32_t Reserved04; /*!< Reserved B00h + (EpNum * 20h) + 04h */
__IO uint32_t DOEPINTF; /*!< USB device IN endpoint interrupt flag register B00h + (EpNum * 20h) + 08h */
uint32_t Reserved0C; /*!< Reserved B00h + (EpNum * 20h) + 0Ch */
__IO uint32_t DOEPLEN; /*!< USB device IN endpoint transfer length register B00h + (EpNum * 20h) + 10h */
__IO uint32_t DOEPDMAADDR; /*!< Device OUT endpoint-x DMA address register B00h + (EpNum * 20h) + 0Ch */
} usb_erout;
typedef struct _usb_regs
{
usb_gr *gr; /*!< USBHS global registers */
usb_dr *dr; /*!< device control and status registers */
usb_hr *hr; /*!< host control and status registers */
usb_erin *er_in[8]; /*!< USB device IN endpoint register */
usb_erout *er_out[8]; /*!< USB device OUT endpoint register */
usb_pr *pr[16]; /*!< USB Host channel-x control register */
__IO uint32_t *HPCS; /*!< USB host port control and status register */
__IO uint32_t *DFIFO[USBHS_MAX_TX_FIFOS];
__IO uint32_t *PWRCLKCTL; /*!< USB power and clock control register */
} usb_core_regs;
/* global OTG control and status register bits definitions */
#define GOTGCS_OV BIT(20) /*!< select OTG version */
#define GOTGCS_BSV BIT(19) /*!< B-Session Valid */
#define GOTGCS_ASV BIT(18) /*!< A-session valid */
#define GOTGCS_DI BIT(17) /*!< debounce interval */
#define GOTGCS_IDPS BIT(16) /*!< id pin status */
#define GOTGCS_EHE BIT(12) /*!< embedded host enable */
#define GOTGCS_DHNPEN BIT(11) /*!< device HNP enable */
#define GOTGCS_HHNPEN BIT(10) /*!< host HNP enable */
#define GOTGCS_HNPREQ BIT(9) /*!< HNP request */
#define GOTGCS_HNPS BIT(8) /*!< HNP successes */
#define GOTGCS_BVOV BIT(7) /*!< override value of B-peripheral session valid */
#define GOTGCS_BVOE BIT(6) /*!< override enable of B-peripheral session valid */
#define GOTGCS_AVOV BIT(5) /*!< override value of A-peripheral session valid */
#define GOTGCS_AVOE BIT(4) /*!< override enable of A-peripheral session valid */
#define GOTGCS_VOV BIT(3) /*!< override value of VBUS valid */
#define GOTGCS_VOE BIT(2) /*!< override enable of VBUS valid */
#define GOTGCS_SRPREQ BIT(1) /*!< SRP request */
#define GOTGCS_SRPS BIT(0) /*!< SRP successes */
/* global OTG interrupt flag register bits definitions */
#define GOTGINTF_IDCHG BIT(20) /*!< ID input change */
#define GOTGINTF_DF BIT(19) /*!< debounce finish */
#define GOTGINTF_ADTO BIT(18) /*!< A-device timeout */
#define GOTGINTF_HNPDET BIT(17) /*!< host negotiation request detected */
#define GOTGINTF_HNPEND BIT(9) /*!< HNP end */
#define GOTGINTF_SRPEND BIT(8) /*!< SRP end */
#define GOTGINTF_SESEND BIT(2) /*!< session end */
/* global AHB control and status register bits definitions */
#define GAHBCS_PTXFTH BIT(8) /*!< periodic Tx FIFO threshold */
#define GAHBCS_TXFTH BIT(7) /*!< tx FIFO threshold */
#define GAHBCS_DMAEN BIT(5) /*!< DMA function Enable */
#define GAHBCS_BURST BITS(1, 4) /*!< the AHB burst type used by DMA */
#define GAHBCS_GINTEN BIT(0) /*!< global interrupt enable */
/* global USB control and status register bits definitions */
#define GUSBCS_FDM BIT(30) /*!< force device mode */
#define GUSBCS_FHM BIT(29) /*!< force host mode */
#define GUSBCS_ULPIEOI BIT(21) /*!< ULPI external over-current indicator */
#define GUSBCS_ULPIEVD BIT(20) /*!< ULPI external VBUS driver */
#define GUSBCS_UTT BITS(10, 13) /*!< USB turnaround time */
#define GUSBCS_HNPCEN BIT(9) /*!< HNP capability enable */
#define GUSBCS_SRPCEN BIT(8) /*!< SRP capability enable */
#define GUSBCS_EMBPHY_FS BIT(6) /*!< embedded FS PHY selected */
#define GUSBCS_EMBPHY_HS BIT(5) /*!< embedded HS PHY selected */
#define GUSBCS_HS_CUR_FE BIT(4) /*!< HS current software enable */
#define GUSBCS_TOC BITS(0, 2) /*!< timeout calibration */
/* global reset control register bits definitions */
#define GRSTCTL_DMAIDL BIT(31) /*!< DMA idle state */
#define GRSTCTL_DMABSY BIT(30) /*!< DMA busy */
#define GRSTCTL_TXFNUM BITS(6, 10) /*!< tx FIFO number */
#define GRSTCTL_TXFF BIT(5) /*!< tx FIFO flush */
#define GRSTCTL_RXFF BIT(4) /*!< rx FIFO flush */
#define GRSTCTL_HFCRST BIT(2) /*!< host frame counter reset */
#define GRSTCTL_HCSRST BIT(1) /*!< HCLK soft reset */
#define GRSTCTL_CSRST BIT(0) /*!< core soft reset */
/* global interrupt flag register bits definitions */
#define GINTF_WKUPIF BIT(31) /*!< wakeup interrupt flag */
#define GINTF_SESIF BIT(30) /*!< session interrupt flag */
#define GINTF_DISCIF BIT(29) /*!< disconnect interrupt flag */
#define GINTF_IDPSC BIT(28) /*!< id pin status change */
#define GINTF_LPMIF BIT(27) /*!< LPM interrupt flag */
#define GINTF_PTXFEIF BIT(26) /*!< periodic tx FIFO empty interrupt flag */
#define GINTF_HCIF BIT(25) /*!< host channels interrupt flag */
#define GINTF_HPIF BIT(24) /*!< host port interrupt flag */
#define GINTF_PXNCIF BIT(21) /*!< periodic transfer not complete interrupt flag */
#define GINTF_ISOONCIF BIT(21) /*!< isochronous OUT transfer not complete interrupt flag */
#define GINTF_ISOINCIF BIT(20) /*!< isochronous IN transfer not complete interrupt flag */
#define GINTF_OEPIF BIT(19) /*!< OUT endpoint interrupt flag */
#define GINTF_IEPIF BIT(18) /*!< IN endpoint interrupt flag */
#define GINTF_EOPFIF BIT(15) /*!< end of periodic frame interrupt flag */
#define GINTF_ISOOPDIF BIT(14) /*!< isochronous OUT packet dropped interrupt flag */
#define GINTF_ENUMFIF BIT(13) /*!< enumeration finished */
#define GINTF_RST BIT(12) /*!< USB reset */
#define GINTF_SP BIT(11) /*!< USB suspend */
#define GINTF_ESP BIT(10) /*!< early suspend */
#define GINTF_GONAK BIT(7) /*!< global OUT NAK effective */
#define GINTF_GNPINAK BIT(6) /*!< global IN non-periodic NAK effective */
#define GINTF_NPTXFEIF BIT(5) /*!< non-periodic tx FIFO empty interrupt flag */
#define GINTF_RXFNEIF BIT(4) /*!< rx FIFO non-empty interrupt flag */
#define GINTF_SOF BIT(3) /*!< start of frame */
#define GINTF_OTGIF BIT(2) /*!< OTG interrupt flag */
#define GINTF_MFIF BIT(1) /*!< mode fault interrupt flag */
#define GINTF_COPM BIT(0) /*!< current operation mode */
/* global interrupt enable register bits definitions */
#define GINTEN_WKUPIE BIT(31) /*!< wakeup interrupt enable */
#define GINTEN_SESIE BIT(30) /*!< session interrupt enable */
#define GINTEN_DISCIE BIT(29) /*!< disconnect interrupt enable */
#define GINTEN_IDPSCIE BIT(28) /*!< id pin status change interrupt enable */
#define GINTEN_LPMIE BIT(27) /*!< LPM interrupt enable */
#define GINTEN_PTXFEIE BIT(26) /*!< periodic tx FIFO empty interrupt enable */
#define GINTEN_HCIE BIT(25) /*!< host channels interrupt enable */
#define GINTEN_HPIE BIT(24) /*!< host port interrupt enable */
#define GINTEN_IPXIE BIT(21) /*!< periodic transfer not complete interrupt enable */
#define GINTEN_ISOONCIE BIT(21) /*!< isochronous OUT transfer not complete interrupt enable */
#define GINTEN_ISOINCIE BIT(20) /*!< isochronous IN transfer not complete interrupt enable */
#define GINTEN_OEPIE BIT(19) /*!< OUT endpoints interrupt enable */
#define GINTEN_IEPIE BIT(18) /*!< IN endpoints interrupt enable */
#define GINTEN_EOPFIE BIT(15) /*!< end of periodic frame interrupt enable */
#define GINTEN_ISOOPDIE BIT(14) /*!< isochronous OUT packet dropped interrupt enable */
#define GINTEN_ENUMFIE BIT(13) /*!< enumeration finish enable */
#define GINTEN_RSTIE BIT(12) /*!< USB reset interrupt enable */
#define GINTEN_SPIE BIT(11) /*!< USB suspend interrupt enable */
#define GINTEN_ESPIE BIT(10) /*!< early suspend interrupt enable */
#define GINTEN_GONAKIE BIT(7) /*!< global OUT NAK effective interrupt enable */
#define GINTEN_GNPINAKIE BIT(6) /*!< global non-periodic IN NAK effective interrupt enable */
#define GINTEN_NPTXFEIE BIT(5) /*!< non-periodic Tx FIFO empty interrupt enable */
#define GINTEN_RXFNEIE BIT(4) /*!< receive FIFO non-empty interrupt enable */
#define GINTEN_SOFIE BIT(3) /*!< start of frame interrupt enable */
#define GINTEN_OTGIE BIT(2) /*!< OTG interrupt enable */
#define GINTEN_MFIE BIT(1) /*!< mode fault interrupt enable */
/* global receive status read and pop register bits definitions */
#define GRSTATRP_RPCKST BITS(17, 20) /*!< received packet status */
#define GRSTATRP_DPID BITS(15, 16) /*!< data PID */
#define GRSTATRP_BCOUNT BITS(4, 14) /*!< byte count */
#define GRSTATRP_CNUM BITS(0, 3) /*!< channel number */
#define GRSTATRP_EPNUM BITS(0, 3) /*!< endpoint number */
/* global receive FIFO length register bits definitions */
#define GRFLEN_RXFD BITS(0, 15) /*!< rx FIFO depth */
/* host non-periodic transmit FIFO length register bits definitions */
#define HNPTFLEN_HNPTXFD BITS(16, 31) /*!< non-periodic Tx FIFO depth */
#define HNPTFLEN_HNPTXRSAR BITS(0, 15) /*!< non-periodic Tx RAM start address */
/* USB IN endpoint 0 transmit FIFO length register bits definitions */
#define DIEP0TFLEN_IEP0TXFD BITS(16, 31) /*!< IN Endpoint 0 Tx FIFO depth */
#define DIEP0TFLEN_IEP0TXRSAR BITS(0, 15) /*!< IN Endpoint 0 TX RAM start address */
/* host non-periodic transmit FIFO/queue status register bits definitions */
#define HNPTFQSTAT_NPTXRQTOP BITS(24, 30) /*!< top entry of the non-periodic Tx request queue */
#define HNPTFQSTAT_NPTXRQS BITS(16, 23) /*!< non-periodic Tx request queue space */
#define HNPTFQSTAT_NPTXFS BITS(0, 15) /*!< non-periodic Tx FIFO space */
#define HNPTFQSTAT_CNUM BITS(27, 30) /*!< channel number*/
#define HNPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */
#define HNPTFQSTAT_TYPE BITS(25, 26) /*!< token type */
#define HNPTFQSTAT_TMF BIT(24) /*!< terminate flag */
/* global core configuration register bits definitions */
#define GCCFG_VDEN BIT(21) /*!< enable of VBUS sensing comparator to detect VBUS valid */
#define GCCFG_SOFOEN BIT(20) /*!< SOF output enable */
#define GCCFG_PWRON BIT(16) /*!< power on */
#define GCCFG_SDMEN BIT(15) /*!< secondary detection mode enable */
#define GCCFG_PEMEN BIT(14) /*!< primary detection mode enable */
#define GCCFG_DCDEN BIT(13) /*!< data connect detection mode enable */
#define GCCFG_BCDEN BIT(12) /*!< battery charging detection enable */
#define GCCFG_PS2F BIT(3) /*!< PS2 detection status */
#define GCCFG_SDF BIT(2) /*!< secondary detection status */
#define GCCFG_PDF BIT(1) /*!< primary detection status */
#define GCCFG_DCDF BIT(0) /*!< battery connect detection status */
/* core ID register bits definitions */
#define CID_CID BITS(0, 31) /*!< core ID */
/* global core LPM configuration register bits definitions */
#define GLPMCFG_BESLEN BIT(28) /*!< LPM Errata selection enable */
#define GLPMCFG_LPMRCS BITS(25, 27) /*!< LPM retry count status */
#define GLPMCFG_LPMSND BIT(24) /*!< send LPM transaction */
#define GLPMCFG_LPMRC BITS(21, 23) /*!< LPM retry count */
#define GLPMCFG_LPMCHI BITS(17, 20) /*!< channel number index */
#define GLPMCFG_RSOK BIT(16) /*!< Resume can be sent after sleep state */
#define GLPMCFG_LPMSLPS BIT(15) /*!< sleep status */
#define GLPMCFG_LPMRSP BITS(13, 14) /*!< response of LPM */
#define GLPMCFG_DSEN BIT(12) /*!< deep sleep enable */
#define GLPMCFG_BESLTH BITS(8, 11) /*!< BESL threshold */
#define GLPMCFG_SSEN BIT(7) /*!< shallow sleep enable */
#define GLPMCFG_REW BIT(6) /*!< bRemoteWake value */
#define GLPMCFG_BESL BITS(2, 5) /*!< best effort service latency */
#define GLPMCFG_ACKLPM BIT(1) /*!< ACK in LPM transaction enable */
#define GLPMCFG_LPMEN BIT(0) /*!< LPM enable */
/* power down register bits definition */
#define PWRD_ADPF BIT(23) /*!< ADP event interrupt flag */
#define PWRD_ADPMEN BIT(0) /*!< ADP module enable */
/* ADP control and status register bits definition */
#define ADPCTL_RWR BITS(27, 28) /*!< read and write request */
#define ADPCTL_ADPTFM BIT(26) /*!< the mask of ADP timeout interrupt flag */
#define ADPCTL_ADPSNFM BIT(25) /*!< the mask of ADP sense interrupt flag */
#define ADPCTL_ADPPRFM BIT(24) /*!< the mask of ADP probe interrupt flag */
#define ADPCTL_ADPTF BIT(23) /*!< ADP timeout interrupt flag */
#define ADPCTL_ADPSNF BIT(22) /*!< ADP sense interrupt flag */
#define ADPCTL_ADPPRF BIT(21) /*!< ADP probe interrupt flag */
#define ADPCTL_ADPEN BIT(20) /*!< ADP enable */
#define ADPCTL_ADPRST BIT(19) /*!< ADP reset */
#define ADPCTL_SNEN BIT(18) /*!< ADP sense enable */
#define ADPCTL_PREN BIT(17) /*!< ADP probe enable */
#define ADPCTL_CHGT BITS(6, 16) /*!< the latest time that VBUS ramps from VADPSINK to VADPPRB */
#define ADPCTL_PERPR BITS(4, 5) /*!< period of probe */
#define ADPCTL_RESOPR BITS(2, 3) /*!< the resolution of CHGT value */
#define ADPCTL_DSCHGPR BITS(0, 1) /*!< Time of probe discharge */
/* USBHS PHY control register bits definitions */
#define PHYCTL_HS_CALEN BIT(31) /*!< HS PHY calibration enable */
#define PHYCTL_HS_CALR BITS(25, 30) /*!< HS PHY calibration value */
#define PHYCTL_HS_RCALR BITS(21, 24) /*!< HS PHY R calibration value */
#define PHYCTL_SQUECH BIT(16) /*!< HS PHY squech flag */
#define PHYCTL_HS_BIST_DONE BIT(15) /*!< HS PHY bist finished flag */
#define PHYCTL_HS_BIST_SUCCESS BIT(14) /*!< HS PHY bist success flag */
#define PHYCTL_HS_BIST_FAIL BIT(13) /*!< HS PHY bist fail flag */
#define PHYCTL_HS_BIST_PKT_SEL BITS(11, 12) /*!< HS PHY bist packet select */
#define PHYCTL_HS_BIST_SEED BITS(3, 10) /*!< HS PHY bist seed */
#define PHYCTL_HS_BIST_EN BIT(2) /*!< HS PHY bist enable */
#define PHYCTL_HS_BIST_RESET BIT(1) /*!< HS PHY bist logic reset */
#define PHYCTL_HS_BIST_START BIT(0) /*!< HS PHY bist start */
/* host periodic transmit FIFO length register bits definitions */
#define HPTFLEN_HPTXFD BITS(16, 31) /*!< host periodic Tx FIFO depth */
#define HPTFLEN_HPTXFSAR BITS(0, 15) /*!< host periodic Tx RAM start address */
/* device IN endpoint transmit FIFO length register bits definitions */
#define DIEPTFLEN_IEPTXFD BITS(16, 31) /*!< IN endpoint Tx FIFO x depth */
#define DIEPTFLEN_IEPTXRSAR BITS(0, 15) /*!< IN endpoint FIFOx Tx x RAM start address */
/* host control register bits definitions */
#define HCTL_SPDFSLS BIT(2) /*!< speed limited to FS and LS */
/* host frame interval register bits definitions */
#define HFT_FRI BITS(0, 15) /*!< frame interval */
/* host frame information remaining register bits definitions */
#define HFINFR_FRT BITS(16, 31) /*!< frame remaining time */
#define HFINFR_FRNUM BITS(0, 15) /*!< frame number */
/* host periodic transmit FIFO/queue status register bits definitions */
#define HPTFQSTAT_PTXREQT BITS(24, 31) /*!< top entry of the periodic Tx request queue */
#define HPTFQSTAT_PTXREQS BITS(16, 23) /*!< periodic Tx request queue space */
#define HPTFQSTAT_PTXFS BITS(0, 15) /*!< periodic Tx FIFO space */
#define HPTFQSTAT_OEFRM BIT(31) /*!< odd/eveb frame */
#define HPTFQSTAT_CNUM BITS(27, 30) /*!< channel number */
#define HPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */
#define HPTFQSTAT_TYPE BITS(25, 26) /*!< token type */
#define HPTFQSTAT_TMF BIT(24) /*!< terminate flag */
#define TFQSTAT_TXFS BITS(0, 15)
#define TFQSTAT_CNUM BITS(27, 30)
/* host all channels interrupt register bits definitions */
#define HACHINT_HACHINT BITS(0, 15) /*!< host all channel interrupts */
/* host all channels interrupt enable register bits definitions */
#define HACHINTEN_CINTEN BITS(0, 15) /*!< channel interrupt enable */
/* host port control and status register bits definitions */
#define HPCS_PS BITS(17, 18) /*!< port speed */
#define HPCS_PTEST BITS(13, 16) /*!< port test control */
#define HPCS_PP BIT(12) /*!< port power */
#define HPCS_PLST BITS(10, 11) /*!< port line status */
#define HPCS_PRST BIT(8) /*!< port reset */
#define HPCS_PSP BIT(7) /*!< port suspend */
#define HPCS_PREM BIT(6) /*!< port resume */
#define HPCS_PEDC BIT(3) /*!< port enable/disable change */
#define HPCS_PE BIT(2) /*!< port enable */
#define HPCS_PCD BIT(1) /*!< port connect detected */
#define HPCS_PCST BIT(0) /*!< port connect status */
/* host channel-x control register bits definitions */
#define HCHCTL_CEN BIT(31) /*!< channel enable */
#define HCHCTL_CDIS BIT(30) /*!< channel disable */
#define HCHCTL_ODDFRM BIT(29) /*!< odd frame */
#define HCHCTL_DAR BITS(22, 28) /*!< device address */
#define HCHCTL_MPC BITS(20, 21) /*!< multiple packet count */
#define HCHCTL_EPTYPE BITS(18, 19) /*!< endpoint type */
#define HCHCTL_LSD BIT(17) /*!< low-speed device */
#define HCHCTL_EPDIR BIT(15) /*!< endpoint direction */
#define HCHCTL_EPNUM BITS(11, 14) /*!< endpoint number */
#define HCHCTL_MPL BITS(0, 10) /*!< maximum packet length */
/* host channel-x split transaction register bits definitions */
#define HCHSTCTL_SPLEN BIT(31) /*!< enable high-speed split transaction */
#define HCHSTCTL_CSPLT BIT(16) /*!< complete-split enable */
#define HCHSTCTL_ISOPCE BITS(14, 15) /*!< isochronous OUT payload continuation encoding */
#define HCHSTCTL_HADDR BITS(7, 13) /*!< HUB address */
#define HCHSTCTL_PADDR BITS(0, 6) /*!< port address */
/* host channel-x interrupt flag register bits definitions */
#define HCHINTF_DTER BIT(10) /*!< data toggle error */
#define HCHINTF_REQOVR BIT(9) /*!< request queue overrun */
#define HCHINTF_BBER BIT(8) /*!< babble error */
#define HCHINTF_USBER BIT(7) /*!< USB bus Error */
#define HCHINTF_NYET BIT(6) /*!< NYET */
#define HCHINTF_ACK BIT(5) /*!< ACK */
#define HCHINTF_NAK BIT(4) /*!< NAK */
#define HCHINTF_STALL BIT(3) /*!< STALL */
#define HCHINTF_DMAER BIT(2) /*!< DMA error */
#define HCHINTF_CH BIT(1) /*!< channel halted */
#define HCHINTF_TF BIT(0) /*!< transfer finished */
/* host channel-x interrupt enable register bits definitions */
#define HCHINTEN_DTERIE BIT(10) /*!< data toggle error interrupt enable */
#define HCHINTEN_REQOVRIE BIT(9) /*!< request queue overrun interrupt enable */
#define HCHINTEN_BBERIE BIT(8) /*!< babble error interrupt enable */
#define HCHINTEN_USBERIE BIT(7) /*!< USB bus error interrupt enable */
#define HCHINTEN_NYETIE BIT(6) /*!< NYET interrupt enable */
#define HCHINTEN_ACKIE BIT(5) /*!< ACK interrupt enable */
#define HCHINTEN_NAKIE BIT(4) /*!< NAK interrupt enable */
#define HCHINTEN_STALLIE BIT(3) /*!< STALL interrupt enable */
#define HCHINTEN_DMAERIE BIT(2) /*!< DMA error interrupt enable */
#define HCHINTEN_CHIE BIT(1) /*!< channel halted interrupt enable */
#define HCHINTEN_TFIE BIT(0) /*!< transfer finished interrupt enable */
/* host channel-x transfer length register bits definitions */
#define HCHLEN_PING BIT(31) /*!< PING token request */
#define HCHLEN_DPID BITS(29, 30) /*!< data PID */
#define HCHLEN_PCNT BITS(19, 28) /*!< packet count */
#define HCHLEN_TLEN BITS(0, 18) /*!< transfer length */
/* host channel-x DMA address register bits definitions */
#define HCHDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */
#define PORT_SPEED(x) (((uint32_t)(x) << 17U) & HPCS_PS) /*!< Port speed */
#define PORT_SPEED_HIGH PORT_SPEED(0U) /*!< high speed */
#define PORT_SPEED_FULL PORT_SPEED(1U) /*!< full speed */
#define PORT_SPEED_LOW PORT_SPEED(2U) /*!< low speed */
#define PIPE_CTL_DAR(x) (((uint32_t)(x) << 22U) & HCHCTL_DAR) /*!< device address */
#define PIPE_CTL_EPTYPE(x) (((uint32_t)(x) << 18U) & HCHCTL_EPTYPE) /*!< endpoint type */
#define PIPE_CTL_EPNUM(x) (((uint32_t)(x) << 11U) & HCHCTL_EPNUM) /*!< endpoint number */
#define PIPE_CTL_EPDIR(x) (((uint32_t)(x) << 15U) & HCHCTL_EPDIR) /*!< endpoint direction */
#define PIPE_CTL_EPMPL(x) (((uint32_t)(x) << 0U) & HCHCTL_MPL) /*!< maximum packet length */
#define PIPE_CTL_LSD(x) (((uint32_t)(x) << 17U) & HCHCTL_LSD) /*!< low-Speed device */
#define PIPE_XFER_PCNT(x) (((uint32_t)(x) << 19U) & HCHLEN_PCNT) /*!< packet count */
#define PIPE_XFER_DPID(x) (((uint32_t)(x) << 29U) & HCHLEN_DPID) /*!< data PID */
#define PIPE_DPID_DATA0 PIPE_XFER_DPID(0) /*!< DATA0 */
#define PIPE_DPID_DATA1 PIPE_XFER_DPID(2) /*!< DATA1 */
#define PIPE_DPID_DATA2 PIPE_XFER_DPID(1) /*!< DATA2 */
#define PIPE_DPID_SETUP PIPE_XFER_DPID(3) /*!< MDATA (non-control)/SETUP (control) */
extern const uint32_t PIPE_DPID[2];
/* device configuration registers bits definitions */
#define DCFG_EOPFT BITS(11, 12) /*!< end of periodic frame time */
#define DCFG_DAR BITS(4, 10) /*!< device address */
#define DCFG_NZLSOH BIT(2) /*!< non-zero-length status OUT handshake */
#define DCFG_DS BITS(0, 1) /*!< device speed */
/* device control registers bits definitions */
#define DCTL_L1RJCT BIT(18) /*!< deep sleep reject */
#define DCTL_POIF BIT(11) /*!< power-on initialization finished */
#define DCTL_CGONAK BIT(10) /*!< clear global OUT NAK */
#define DCTL_SGONAK BIT(9) /*!< set global OUT NAK */
#define DCTL_CGINAK BIT(8) /*!< clear global IN NAK */
#define DCTL_SGINAK BIT(7) /*!< set global IN NAK */
#define DCTL_DTEST BITS(4, 6) /*!< device test control */
#define DCTL_GONS BIT(3) /*!< global OUT NAK status */
#define DCTL_GINS BIT(2) /*!< global IN NAK status */
#define DCTL_SD BIT(1) /*!< soft disconnect */
#define DCTL_RWKUP BIT(0) /*!< remote wakeup */
/* device status registers bits definitions */
#define DSTAT_FNRSOF BITS(8, 21) /*!< the frame number of the received SOF. */
#define DSTAT_ES BITS(1, 2) /*!< enumerated speed */
#define DSTAT_SPST BIT(0) /*!< suspend status */
/* device IN endpoint common interrupt enable registers bits definitions */
#define DIEPINTEN_NAKEN BIT(13) /*!< NAK handshake sent by USBHS interrupt enable bit */
#define DIEPINTEN_TXFEEN BIT(7) /*!< transmit FIFO empty interrupt enable bit */
#define DIEPINTEN_IEPNEEN BIT(6) /*!< IN endpoint NAK effective interrupt enable bit */
#define DIEPINTEN_EPTXFUDEN BIT(4) /*!< endpoint Tx FIFO underrun interrupt enable bit */
#define DIEPINTEN_CITOEN BIT(3) /*!< control In Timeout interrupt enable bit */
#define DIEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */
#define DIEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */
/* device OUT endpoint common interrupt enable registers bits definitions */
#define DOEPINTEN_NYETEN BIT(14) /*!< NYET handshake is sent interrupt enable bit */
#define DOEPINTEN_BTBSTPEN BIT(6) /*!< back-to-back SETUP packets interrupt enable bit */
#define DOEPINTEN_EPRXFOVREN BIT(4) /*!< endpoint Rx FIFO overrun interrupt enable bit */
#define DOEPINTEN_STPFEN BIT(3) /*!< SETUP phase finished interrupt enable bit */
#define DOEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */
#define DOEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */
/* device all endpoints interrupt registers bits definitions */
#define DAEPINT_OEPITB BITS(16, 23) /*!< device all OUT endpoint interrupt bits */
#define DAEPINT_IEPITB BITS(0, 7) /*!< device all IN endpoint interrupt bits */
/* device all endpoints interrupt enable registers bits definitions */
#define DAEPINTEN_OEPIE BITS(16, 23) /*!< OUT endpoint interrupt enable */
#define DAEPINTEN_IEPIE BITS(0, 7) /*!< IN endpoint interrupt enable */
/* device VBUS discharge time registers bits definitions */
#define DVBUSDT_DVBUSDT BITS(0, 15) /*!< device VBUS discharge time */
/* device VBUS pulsing time registers bits definitions */
#define DVBUSPT_DVBUSPT BITS(0, 11) /*!< device VBUS pulsing time */
/* device IN endpoint FIFO empty interrupt enable register bits definitions */
#define DIEPFEINTEN_IEPTXFEIE BITS(0, 5) /*!< IN endpoint Tx FIFO empty interrupt enable bits */
/* device endpoint 0 control register bits definitions */
#define DEP0CTL_EPEN BIT(31) /*!< endpoint enable */
#define DEP0CTL_EPD BIT(30) /*!< endpoint disable */
#define DEP0CTL_SNAK BIT(27) /*!< set NAK */
#define DEP0CTL_CNAK BIT(26) /*!< clear NAK */
#define DIEP0CTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */
#define DEP0CTL_STALL BIT(21) /*!< STALL handshake */
#define DOEP0CTL_SNOOP BIT(20) /*!< snoop mode */
#define DEP0CTL_EPTYPE BITS(18, 19) /*!< endpoint type */
#define DEP0CTL_NAKS BIT(17) /*!< NAK status */
#define DEP0CTL_EPACT BIT(15) /*!< endpoint active */
#define DEP0CTL_MPL BITS(0, 1) /*!< maximum packet length */
/* device endpoint x control register bits definitions */
#define DEPCTL_EPEN BIT(31) /*!< endpoint enable */
#define DEPCTL_EPD BIT(30) /*!< endpoint disable */
#define DEPCTL_SODDFRM BIT(29) /*!< set odd frame */
#define DEPCTL_SD1PID BIT(29) /*!< set DATA1 PID */
#define DEPCTL_SEVNFRM BIT(28) /*!< set even frame */
#define DEPCTL_SD0PID BIT(28) /*!< set DATA0 PID */
#define DEPCTL_SNAK BIT(27) /*!< set NAK */
#define DEPCTL_CNAK BIT(26) /*!< clear NAK */
#define DIEPCTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */
#define DEPCTL_STALL BIT(21) /*!< STALL handshake */
#define DOEPCTL_SNOOP BIT(20) /*!< snoop mode */
#define DEPCTL_EPTYPE BITS(18, 19) /*!< endpoint type */
#define DEPCTL_NAKS BIT(17) /*!< NAK status */
#define DEPCTL_EOFRM BIT(16) /*!< even/odd frame */
#define DEPCTL_DPID BIT(16) /*!< endpoint data PID */
#define DEPCTL_EPACT BIT(15) /*!< endpoint active */
#define DEPCTL_MPL BITS(0, 10) /*!< maximum packet length */
/* device IN endpoint-x interrupt flag register bits definitions */
#define DIEPINTF_NAK BIT(13) /*!< NAK handshake sent by USBHS */
#define DIEPINTF_TXFE BIT(7) /*!< transmit FIFO empty */
#define DIEPINTF_IEPNE BIT(6) /*!< IN endpoint NAK effective */
#define DIEPINTF_EPTXFUD BIT(4) /*!< endpoint Tx FIFO underrun */
#define DIEPINTF_CITO BIT(3) /*!< control In Timeout interrupt */
#define DIEPINTF_EPDIS BIT(1) /*!< endpoint disabled */
#define DIEPINTF_TF BIT(0) /*!< transfer finished */
/* device OUT endpoint-x interrupt flag register bits definitions */
#define DOEPINTF_NYET BIT(14) /*!< NYET handshake is sent */
#define DOEPINTF_BTBSTP BIT(6) /*!< back-to-back SETUP packets */
#define DOEPINTF_EPRXFOVR BIT(4) /*!< endpoint Rx FIFO overrun */
#define DOEPINTF_STPF BIT(3) /*!< SETUP phase finished */
#define DOEPINTF_EPDIS BIT(1) /*!< endpoint disabled */
#define DOEPINTF_TF BIT(0) /*!< transfer finished */
/* device IN endpoint 0 transfer length register bits definitions */
#define DIEP0LEN_PCNT BITS(19, 20) /*!< packet count */
#define DIEP0LEN_TLEN BITS(0, 6) /*!< transfer length */
/* device OUT endpoint 0 transfer length register bits definitions */
#define DOEP0LEN_STPCNT BITS(29, 30) /*!< SETUP packet count */
#define DOEP0LEN_PCNT BIT(19) /*!< packet count */
#define DOEP0LEN_TLEN BITS(0, 6) /*!< transfer length */
/* device OUT endpoint-x transfer length register bits definitions */
#define DOEPLEN_RXDPID BITS(29, 30) /*!< received data PID */
#define DOEPLEN_STPCNT BITS(29, 30) /*!< SETUP packet count */
#define DIEPLEN_MCNT BITS(29, 30) /*!< multi count */
#define DEPLEN_PCNT BITS(19, 28) /*!< packet count */
#define DEPLEN_TLEN BITS(0, 18) /*!< transfer length */
/* device IN endpoint-x DMA address register bits definitions */
#define DIEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */
/* device OUT endpoint-x DMA address register bits definitions */
#define DOEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */
/* device IN endpoint-x transmit FIFO status register bits definitions */
#define DIEPTFSTAT_IEPTFS BITS(0, 15) /*!< IN endpoint Tx FIFO space remaining */
/* USB power and clock registers bits definition */
#define PWRCLKCTL_DSLEEP BIT(7) /*!< PHY is in deep sleep status */
#define PWRCLKCTL_SSLEEP BIT(6) /*!< PHY is in shallow sleep status */
#define PWRCLKCTL_SCGEN BIT(5) /*!< When this bit is set, the internal clock gating is enabled */
#define PWRCLKCTL_SUSP BIT(4) /*!< PHY is in suspend status */
#define PWRCLKCTL_SHCLK BIT(1) /*!< stop HCLK */
#define PWRCLKCTL_SUCLK BIT(0) /*!< stop the USB clock */
#define RSTAT_GOUT_NAK 1U /*!< global OUT NAK (triggers an interrupt) */
#define RSTAT_DATA_UPDT 2U /*!< OUT data packet received */
#define RSTAT_XFER_COMP 3U /*!< OUT transfer completed (triggers an interrupt) */
#define RSTAT_SETUP_COMP 4U /*!< SETUP transaction completed (triggers an interrupt) */
#define RSTAT_SETUP_UPDT 6U /*!< SETUP data packet received */
#define DSTAT_EM_HS_PHY_30MHZ_60MHZ 0U /*!< USB enumerate speed use high-speed PHY clock in 30MHz or 60MHz */
#define DSTAT_EM_FS_PHY_30MHZ_60MHZ 1U /*!< USB enumerate speed use full-speed PHY clock in 30MHz or 60MHz */
#define DSTAT_EM_LS_PHY_6MHZ 2U /*!< USB enumerate speed use low-speed PHY clock in 6MHz */
#define DSTAT_EM_FS_PHY_48MHZ 3U /*!< USB enumerate speed use full-speed PHY clock in 48MHz */
#define DPID_DATA0 0U /*!< device endpoint data PID is DATA0 */
#define DPID_DATA1 2U /*!< device endpoint data PID is DATA1 */
#define DPID_DATA2 1U /*!< device endpoint data PID is DATA2 */
#define DPID_MDATA 3U /*!< device endpoint data PID is MDATA */
#define GAHBCS_DMAINCR(regval) (GAHBCS_BURST & ((regval) << 1U)) /*!< AHB burst type used by DMA */
#define DMA_INCR0 GAHBCS_DMAINCR(0U) /*!< single burst type used by DMA*/
#define DMA_INCR1 GAHBCS_DMAINCR(1U) /*!< 4-beat incrementing burst type used by DMA */
#define DMA_INCR4 GAHBCS_DMAINCR(3U) /*!< 8-beat incrementing burst type used by DMA */
#define DMA_INCR8 GAHBCS_DMAINCR(5U) /*!< 16-beat incrementing burst type used by DMA */
#define DMA_INCR16 GAHBCS_DMAINCR(7U) /*!< 32-beat incrementing burst type used by DMA */
#define DCFG_PFRI(regval) (DCFG_EOPFT & ((regval) << 11U)) /*!< end of periodic frame time configuration */
#define FRAME_INTERVAL_80 DCFG_PFRI(0U) /*!< 80% of the frame time */
#define FRAME_INTERVAL_85 DCFG_PFRI(1U) /*!< 85% of the frame time */
#define FRAME_INTERVAL_90 DCFG_PFRI(2U) /*!< 90% of the frame time */
#define FRAME_INTERVAL_95 DCFG_PFRI(3U) /*!< 95% of the frame time */
#define DCFG_DEVSPEED(regval) (DCFG_DS & ((regval) << 0U)) /*!< device speed configuration */
#define USB_SPEED_INP_HIGH DCFG_DEVSPEED(0U) /*!< device internal PHY high speed */
#define USB_SPEED_INP_FULL DCFG_DEVSPEED(1U) /*!< device internal PHY full speed */
#define DEP0_MPL(regval) (DEP0CTL_MPL & ((regval) << 0U)) /*!< maximum packet length configuration */
#define EP0MPL_64 DEP0_MPL(0U) /*!< maximum packet length 64 bytes */
#define EP0MPL_32 DEP0_MPL(1U) /*!< maximum packet length 32 bytes */
#define EP0MPL_16 DEP0_MPL(2U) /*!< maximum packet length 16 bytes */
#define EP0MPL_8 DEP0_MPL(3U) /*!< maximum packet length 8 bytes */
#define DOEP0_TLEN(regval) (DOEP0LEN_TLEN & ((regval) << 0U)) /*!< Transfer length */
#define DOEP0_PCNT(regval) (DOEP0LEN_PCNT & ((regval) << 19U)) /*!< Packet count */
#define DOEP0_STPCNT(regval) (DOEP0LEN_STPCNT & ((regval) << 29U)) /*!< SETUP packet count */
#define GRXSTS_PKTSTS_IN 2U
#define GRXSTS_PKTSTS_IN_XFER_COMP 3U
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U
#define GRXSTS_PKTSTS_CH_HALTED 7U
#define DEVICE_MODE 0U /*!< device mode */
#define HOST_MODE 1U /*!< host mode */
#define OTG_MODE 2U /*!< OTG mode */
#define HCTL_30_60MHZ 0U /*!< USB clock 30-60MHZ */
#define HCTL_48MHZ 1U /*!< USB clock 48MHZ */
#define HCTL_6MHZ 2U /*!< USB clock 6MHZ */
#define USBHS_MAX_PACKET_SIZE 512U /*!< USBHS max packet size */
#define USBHS_MAX_CHANNEL_COUNT 16U /*!< USBHS host channel count */
#define USBHS_MAX_EP_COUNT 8U /*!< USBHS device endpoint count */
#define USBHS_MAX_FIFO_WORDLEN 1280U /*!< USBHS max fifo size in words */
#define USB_DATA_FIFO_OFFSET 0x1000U /*!< USB data fifo offset */
#define USB_DATA_FIFO_SIZE 0x1000U /*!< USB data fifo size */
typedef enum
{
USB_EMBEDDED_PHY_FS = 0U, /*!< USB embedded FS PHY */
USB_EMBEDDED_PHY_HS, /*!< USB embedded HS PHY */
USB_ULPI_PHY_EXTERNAL /*!< USB external ULPI PHY */
} usb_phy_enum;
enum usb_reg_offset
{
USB_REG_OFFSET_CORE = 0x0000U, /*!< global OTG control and status register */
USB_REG_OFFSET_DEV = 0x0800U, /*!< device mode control and status registers */
USB_REG_OFFSET_EP = 0x0020U, /*!< offset of each endpoint */
USB_REG_OFFSET_EP_IN = 0x0900U, /*!< device IN endpoint 0 control register */
USB_REG_OFFSET_EP_OUT = 0x0B00U, /*!< device OUT endpoint 0 control register */
USB_REG_OFFSET_HOST = 0x0400U, /*!< host control register */
USB_REG_OFFSET_CH = 0x0020U, /*!< offset of each channel */
USB_REG_OFFSET_PORT = 0x0440U, /*!< host port control and status register */
USB_REG_OFFSET_CH_INOUT = 0x0500U, /*!< host channel-x control registers */
USB_REG_OFFSET_PWRCLKCTL = 0x0E00U /*!< power and clock register */
};
enum USB_SPEED
{
USB_SPEED_UNKNOWN = 0, /*!< USB speed unknown */
USB_SPEED_LOW, /*!< USB speed low */
USB_SPEED_FULL, /*!< USB speed full */
USB_SPEED_HIGH /*!< USB speed high */
};
#define EP0_OUT ((uint8_t)0x00U) /*!< endpoint out 0 */
#define EP0_IN ((uint8_t)0x80U) /*!< endpoint in 0 */
#define EP1_OUT ((uint8_t)0x01U) /*!< endpoint out 1 */
#define EP1_IN ((uint8_t)0x81U) /*!< endpoint in 1 */
#define EP2_OUT ((uint8_t)0x02U) /*!< endpoint out 2 */
#define EP2_IN ((uint8_t)0x82U) /*!< endpoint in 2 */
#define EP3_OUT ((uint8_t)0x03U) /*!< endpoint out 3 */
#define EP3_IN ((uint8_t)0x83U) /*!< endpoint in 3 */
#define EP4_OUT ((uint8_t)0x04U) /*!< endpoint out 4 */
#define EP4_IN ((uint8_t)0x84U) /*!< endpoint in 4 */
#define EP5_OUT ((uint8_t)0x05U) /*!< endpoint out 5 */
#define EP5_IN ((uint8_t)0x85U) /*!< endpoint in 5 */
#define EP6_OUT ((uint8_t)0x06U) /*!< endpoint out 6 */
#define EP6_IN ((uint8_t)0x86U) /*!< endpoint in 6 */
#define EP7_OUT ((uint8_t)0x06U) /*!< endpoint out 7 */
#define EP7_IN ((uint8_t)0x86U) /*!< endpoint in 7 */
#endif /* DRV_USB_REGS_H */

28
828ECO/drivers/include/usb/drv_usbd_int.h

@ -0,0 +1,28 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef DRV_USBD_INT_H
#define DRV_USBD_INT_H
#include "drv_usb_core.h"
#include "drv_usb_dev.h"
/* function declarations */
#ifdef USB_DEDICATED_EP1_ENABLED
/* USB dedicated OUT endpoint 1 interrupt service routine handler */
uint32_t usbd_int_dedicated_ep1out(usb_core_driver *udev);
/* USB dedicated IN endpoint 1 interrupt service routine handler */
uint32_t usbd_int_dedicated_ep1in(usb_core_driver *udev);
#endif /* USB_DEDICATED_EP1_ENABLED */
/* USB device-mode interrupts global service routine handler */
void usbd_isr(usb_core_driver *udev);
#endif /* DRV_USBD_INT_H */

19
828ECO/drivers/include/usb/drv_usbh_int.h

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef DRV_USBH_INT_H
#define DRV_USBH_INT_H
#include "drv_usb_host.h"
/* handle global host interrupt */
uint32_t usbh_isr(usb_core_driver *udev);
#endif /* DRV_USBH_INT_H */

48
828ECO/drivers/include/usb/drv_usbh_pipe.h

@ -0,0 +1,48 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef __DRV_USBH_PIPE_H
#define __DRV_USBH_PIPE_H
#include "drv_usb_host.h"
#define HC_MAX 8U
#define HC_OK 0x0000U
#define HC_USED 0x8000U
#define HC_ERROR 0xFFFFU
#define HC_USED_MASK 0x7FFFU
/* allocate a new pipe */
uint8_t usbh_pipe_allocate(usb_core_driver *pudev, uint8_t ep_addr);
/* delete all USB host pipe */
uint8_t usbh_pipe_delete(usb_core_driver *pudev);
/* free a pipe */
uint8_t usbh_pipe_free(usb_core_driver *pudev, uint8_t pp_num);
/* create a pipe */
uint8_t usbh_pipe_create(usb_core_driver *pudev,
uint8_t dev_addr,
uint8_t dev_speed,
uint8_t pp_num,
uint8_t ep_num,
uint8_t ep_type,
uint16_t ep_mpl);
/* modify a pipe */
uint8_t usbh_pipe_update(usb_core_driver *pudev,
uint8_t pp_num,
uint8_t dev_addr,
uint32_t dev_speed,
uint16_t ep_mpl);
#endif /* __DRV_USBH_PIPE_H */

41
828ECO/drivers/include/usb/drv_usbh_transc.h

@ -0,0 +1,41 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef __DRV_USBH_TRANSC_H
#define __DRV_USBH_TRANSC_H
#include "drv_usb_host.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
/* send the setup packet to the USB device */
usbh_status usbh_ctlsetup_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num);
/* send a data packet to the USB device */
usbh_status usbh_data_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len);
/* receive a data packet from the USB device */
usbh_status usbh_data_recev(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len);
/* get USB URB state */
static inline usb_urb_state usbh_urbstate_get(usb_core_driver *pudev, uint8_t pp_num)
{
return pudev->host.pipe[pp_num].urb_state;
}
/* get USB transfer data count */
static inline uint32_t usbh_xfercount_get(usb_core_driver *pudev, uint8_t pp_num)
{
return pudev->host.backup_xfercount[pp_num];
}
#endif /* BSP_USING_USB && RT_USING_USB_HOST */
#endif /* __DRV_USBH_TRANSC_H */

139
828ECO/drivers/include/usb/usb_conf.h

@ -0,0 +1,139 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#ifndef USB_CONF_H
#define USB_CONF_H
#include <board.h>
#if defined(BSP_USING_USB)
#if defined(SOC_SERIES_GD32H75E)
#include "gd32h75e.h"
#elif defined(SOC_SERIES_GD32H7xx)
#include "gd32h7xx.h"
#endif
/* USB Core and PHY interface configuration */
/* USB HS PHY CONFIGURATION */
/* on-chip full-speed USB PHY */
#ifdef USE_USB_FS
#define OC_FS_PHY
#endif
/* on-chip high-speed USB PHY */
#ifdef USE_USB_HS
#define OC_HS_PHY
#endif /* USE_USB_HS */
#if defined(RT_USING_USB_DEVICE)
#define USB_SOF_OUTPUT 0U
/* USB FIFO size config */
#define RX_FIFO_SIZE 512U
#define TX0_FIFO_SIZE 128U
#define TX1_FIFO_SIZE 384U
#define TX2_FIFO_SIZE 0U
#define TX3_FIFO_SIZE 0U
#define TX4_FIFO_SIZE 0U
#define TX5_FIFO_SIZE 0U
#define TX6_FIFO_SIZE 0U
#define TX7_FIFO_SIZE 0U
#elif defined(RT_USING_USB_HOST)
#define USBH_USE_RTOS
#define USB_SOF_OUTPUT 1U
/* USB FIFO size config */
#define USB_RX_FIFO_SIZE 512
#define USB_HTX_NPFIFO_SIZE 256
#define USB_HTX_PFIFO_SIZE 256
#endif
/* General USB Configuration */
#define USB_LOW_POWER 0U
/* if uncomment it, need jump to USB JP */
//#define VBUS_SENSING_ENABLED
//#define USB_INTERNAL_DMA_ENABLED
//#define USB_DEDICATED_EP1_ENABLED
/* End General USB Configuration */
#ifdef USE_ULPI_PHY
#define USB_EXTERNAL_ULPI_PHY_ENABLED
#else
#ifdef OC_FS_PHY
#define USB_EMBEDDED_FS_PHY_ENABLED
#elif defined(OC_HS_PHY)
#define USB_EMBEDDED_HS_PHY_ENABLED
#else
#error "PHY is not selected"
#endif /* OC_FS_PHY */
#endif /* USE_ULPI_PHY */
#if defined(RT_USING_USB_HOST)
#define USE_HOST_MODE
#elif defined(RT_USING_USB_DEVICE)
#define USE_DEVICE_MODE
#else
#warning "Please select the USB mode as USBD or USBH; otherwise, the USE_OTG_MODE will be enabled by default."
#define USE_OTG_MODE
#endif
#ifndef OC_FS_PHY
#ifndef OC_HS_PHY
#error "OC_FS_PHY or OC_HS_PHY should be defined!"
#endif
#endif /* OC_FS_PHY */
#ifndef RT_USING_USB_DEVICE
#ifndef RT_USING_USB_HOST
#error "RT_USING_USB_DEVICE or RT_USING_USB_HOST should be defined!"
#endif
#endif /* USE_DEVICE_MODE */
#ifndef USE_USB_HS
#ifndef USE_USB_FS
#error "USE_USB_HS or USE_USB_FS should be defined!"
#endif
#endif /* USE_USB_HS */
/* all variables and data structures during the transaction process should be 4-bytes aligned */
#if defined(__GNUC__) /* GNU Compiler */
#define __ALIGN_END __attribute__((aligned(4)))
#define __ALIGN_BEGIN
#else
#define __ALIGN_END
#if defined(__CC_ARM) /* ARM Compiler */
#define __ALIGN_BEGIN __align(4)
#elif defined(__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#elif defined(__TASKING__)/* TASKING Compiler */
#define __ALIGN_BEGIN __align(4)
#endif /* __CC_ARM */
#endif /* __GNUC__ */
/* __packed keyword used to decrease the data type alignment to 1-byte */
#if defined(__GNUC__) /* GNU Compiler */
#ifndef __packed
#define __packed __unaligned
#endif
#elif defined(__TASKING__) /* TASKING Compiler */
#define __packed __unaligned
#endif /* __GNUC__ */
#endif /* BSP_USING_USB */
#endif /* USB_CONF_H */

285
828ECO/drivers/synopsys_emac.c

@ -0,0 +1,285 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include <rtthread.h>
#if defined(RT_USING_SAL) && defined(RT_USING_NETDEV) && defined(RT_USING_LWIP)
#include "synopsys_emac.h"
#include "gd32h7xx_enet.h"
/* The state of enet initialization */
volatile uint32_t enet_init_state = 0;
/* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */
extern EMAC_DMADESCTypeDef *DMATxDescToSet;
extern EMAC_DMADESCTypeDef *DMARxDescToGet;
/**
* Initializes the ETHERNET peripheral according to the specified
*/
rt_uint32_t EMAC_init(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t SystemCoreClock)
{
/*-------------------------------- Reset ethernet -------------------------------*/
enet_deinit(ENET0);
enet_software_reset(ENET0);
/* configure the parameters which are usually less cared for enet initialization */
enet_initpara_config(HALFDUPLEX_OPTION, ENET_CARRIERSENSE_DISABLE | ENET_RECEIVEOWN_ENABLE | ENET_RETRYTRANSMISSION_DISABLE | ENET_BACKOFFLIMIT_10 | ENET_DEFERRALCHECK_DISABLE);
/*-------------------------------- Initialize ENET ------------------------------*/
#ifdef RT_LWIP_USING_HW_CHECKSUM
enet_init_state = enet_init(ENET0, ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_BROADCAST_FRAMES_PASS);
#else
enet_init_state = enet_init(ENET0, ENET_AUTO_NEGOTIATION, ENET_NO_AUTOCHECKSUM, ENET_BROADCAST_FRAMES_PASS);
#endif
if (SUCCESS != enet_init_state)
{
rt_kprintf("enet init failed. \r\n");
return EMAC_ERROR;
}
else
{
/* Return Ethernet configuration success */
return EMAC_SUCCESS;
}
}
/**
* Enables or disables the specified ETHERNET DMA interrupts.
*/
void EMAC_INT_config(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT, rt_bool_t NewState)
{
if (NewState)
{
/* Enable the selected ETHERNET DMA interrupts */
ETHERNET_MAC->IER |= EMAC_DMA_IT;
}
else
{
/* Disable the selected ETHERNET DMA interrupts */
ETHERNET_MAC->IER &= (~(rt_uint32_t)EMAC_DMA_IT);
}
}
/**
* Configures the selected MAC address.
*/
void EMAC_MAC_Addr_config(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t MacAddr, rt_uint8_t *Addr)
{
rt_uint32_t value;
/* Calculate the selectecd MAC address high register */
value = ((rt_uint32_t)Addr[5] << 8) | (rt_uint32_t)Addr[4];
/* Load the selectecd MAC address high register */
//(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_HBASE + MacAddr)) = value;
ETHERNET_MAC->MARs[MacAddr].MARH = value;
/* Calculate the selectecd MAC address low register */
value = ((rt_uint32_t)Addr[3] << 24) | ((rt_uint32_t)Addr[2] << 16) | ((rt_uint32_t)Addr[1] << 8) | Addr[0];
/* Load the selectecd MAC address low register */
//(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_LBASE + MacAddr)) = value;
ETHERNET_MAC->MARs[MacAddr].MARL = value;
}
/**
* Enables or disables the MAC transmission.
*/
void EMAC_MACTransmissionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState)
{
if (NewState)
{
/* Enable the MAC transmission */
ETHERNET_MAC->MCR |= EMAC_MACCR_TE;
}
else
{
/* Disable the MAC transmission */
ETHERNET_MAC->MCR &= ~EMAC_MACCR_TE;
}
}
/**
* Clears the ETHERNET transmit FIFO.
*/
void EMAC_FlushTransmitFIFO(struct rt_synopsys_eth *ETHERNET_MAC)
{
/* Set the Flush Transmit FIFO bit */
ETHERNET_MAC->OMR |= EMAC_DMAOMR_FTF;
}
/**
* Enables or disables the MAC reception.
*/
void EMAC_MACReceptionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState)
{
if (NewState)
{
/* Enable the MAC reception */
ETHERNET_MAC->MCR |= EMAC_MACCR_RE;
}
else
{
/* Disable the MAC reception */
ETHERNET_MAC->MCR &= ~EMAC_MACCR_RE;
}
}
/**
* Enables or disables the DMA transmission.
*/
void EMAC_DMATransmissionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState)
{
if (NewState)
{
/* Enable the DMA transmission */
ETHERNET_MAC->OMR |= EMAC_DMAOMR_ST;
}
else
{
/* Disable the DMA transmission */
ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_ST;
}
}
/**
* Enables or disables the DMA reception.
*/
void EMAC_DMAReceptionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState)
{
if (NewState)
{
/* Enable the DMA reception */
ETHERNET_MAC->OMR |= EMAC_DMAOMR_SR;
}
else
{
/* Disable the DMA reception */
ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_SR;
}
}
/**
* Enables ENET MAC and DMA reception/transmission
*/
void EMAC_start(struct rt_synopsys_eth *ETHERNET_MAC)
{
/* Enable transmit state machine of the MAC for transmission on the MII */
EMAC_MACTransmissionCmd(ETHERNET_MAC, RT_TRUE);
/* Flush Transmit FIFO */
enet_txfifo_flush(ENET0);
/* Enable receive state machine of the MAC for reception from the MII */
EMAC_MACReceptionCmd(ETHERNET_MAC, RT_TRUE);
/* Start DMA transmission */
EMAC_DMATransmissionCmd(ETHERNET_MAC, RT_TRUE);
/* Start DMA reception */
EMAC_DMAReceptionCmd(ETHERNET_MAC, RT_TRUE);
}
/**
* Clears the ETHERNET's DMA interrupt pending bit.
*/
void EMAC_clear_pending(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t pending)
{
/* Clear the selected ETHERNET DMA IT */
ETHERNET_MAC->SR = (rt_uint32_t)pending;
}
/**
* Resumes the DMA Transmission by writing to the DmaRxPollDemand register
* (the data written could be anything). This forces the DMA to resume reception.
*/
void EMAC_resume_reception(struct rt_synopsys_eth *ETHERNET_MAC)
{
ETHERNET_MAC->RPDR = 0;
}
/**
* Resumes the DMA Transmission by writing to the DmaTxPollDemand register
* (the data written could be anything). This forces the DMA to resume transmission.
*/
void EMAC_resume_transmission(struct rt_synopsys_eth *ETHERNET_MAC)
{
ETHERNET_MAC->TPDR = 0;
}
/**
* Read a PHY register
*/
rt_uint16_t EMAC_PHY_read(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg)
{
rt_uint32_t value = 0;
volatile rt_uint32_t timeout = 0;
/* Get the ETHERNET MACMIIAR value */
value = ETHERNET_MAC->GAR;
/* Keep only the CSR Clock Range CR[2:0] bits value */
value &= ~MACMIIAR_CR_MASK;
/* Prepare the MII address register value */
value |= (((rt_uint32_t)PHYAddress << 11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
value |= (((rt_uint32_t)PHYReg << 6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
value &= ~EMAC_MACMIIAR_MW; /* Set the read mode */
value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
/* Write the result value into the MII Address register */
ETHERNET_MAC->GAR = value;
/* Check for the Busy flag */
do
{
timeout++;
value = ETHERNET_MAC->GAR;
} while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_READ_TO));
/* Return ERROR in case of timeout */
if (timeout == PHY_READ_TO)
{
return (rt_uint16_t)EMAC_ERROR;
}
/* Return data register value */
return (rt_uint16_t)(ETHERNET_MAC->GDR);
}
/**
* Write to a PHY register
*/
rt_uint32_t EMAC_PHY_write(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg, rt_uint16_t PHYValue)
{
rt_uint32_t value = 0;
volatile rt_uint32_t timeout = 0;
/* Get the ETHERNET MACMIIAR value */
value = ETHERNET_MAC->GAR;
/* Keep only the CSR Clock Range CR[2:0] bits value */
value &= ~MACMIIAR_CR_MASK;
/* Prepare the MII register address value */
value |= (((rt_uint32_t)PHYAddress << 11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
value |= (((rt_uint32_t)PHYReg << 6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
value |= EMAC_MACMIIAR_MW; /* Set the write mode */
value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
/* Give the value to the MII data register */
ETHERNET_MAC->GDR = PHYValue;
/* Write the result value into the MII Address register */
ETHERNET_MAC->GAR = value;
/* Check for the Busy flag */
do
{
timeout++;
value = ETHERNET_MAC->GAR;
} while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_WRITE_TO));
/* Return ERROR in case of timeout */
if (timeout == PHY_WRITE_TO)
{
return EMAC_ERROR;
}
/* Return SUCCESS */
return EMAC_SUCCESS;
}
#endif /* RT_USING_SAL && RT_USING_NETDEV && RT_USING_LWIP */

336
828ECO/drivers/usb/drv_otghs_dev.c

@ -0,0 +1,336 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_otghs_dev.h"
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "drv_usb_hw.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE)
usb_core_driver gd_usb_core;
static struct udcd _gd_udc;
#ifdef USE_USB_FS
static struct ep_id _ep_pool[] = {
{ 0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED },
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED },
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED },
{ 0x2, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED },
{ 0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED },
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED },
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED },
{ 0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
};
#elif defined USE_USB_HS
static struct ep_id _ep_pool[] = {
{ 0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED },
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED },
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 512, ID_UNASSIGNED },
{ 0x2, USB_EP_ATTR_INT, USB_DIR_IN, 512, ID_UNASSIGNED },
{ 0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 512, ID_UNASSIGNED },
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 512, ID_UNASSIGNED },
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 512, ID_UNASSIGNED },
{ 0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
};
#endif
void usbd_reset_callback(void)
{
rt_usbd_reset_handler(&_gd_udc);
}
void usbd_setup_stage_callback(struct urequest *setup_packet)
{
rt_usbd_ep0_setup_handler(&_gd_udc, setup_packet);
}
void usbd_data_in_stage_callback(uint8_t epnum, uint16_t data_count)
{
if (epnum == 0)
{
rt_usbd_ep0_in_handler(&_gd_udc);
}
else
{
rt_usbd_ep_in_handler(&_gd_udc, 0x80 | epnum, data_count);
}
}
void usbd_connect_callback(void)
{
rt_usbd_connect_handler(&_gd_udc);
}
void usbd_sof_callback(void)
{
rt_usbd_sof_handler(&_gd_udc);
}
void usbd_disconnect_callback(void)
{
rt_usbd_disconnect_handler(&_gd_udc);
}
void usbd_data_out_stage_callback(uint8_t epnum, uint16_t data_count)
{
if (epnum == 0)
{
rt_usbd_ep0_out_handler(&_gd_udc, data_count);
}
else
{
rt_usbd_ep_out_handler(&_gd_udc, epnum, data_count);
}
}
void usbd_set_connection_state(uint8_t state)
{
if (state == 1)
{
usb_dev_connect(&gd_usb_core);
usb_mdelay(3);
}
else
{
usb_dev_disconnect(&gd_usb_core);
usb_mdelay(3);
}
}
static rt_err_t _ep_set_stall(rt_uint8_t address)
{
usb_ep_stall(&gd_usb_core, address);
return RT_EOK;
}
static rt_err_t _ep_clear_stall(rt_uint8_t address)
{
usb_ep_clrstall(&gd_usb_core, address);
return RT_EOK;
}
static rt_err_t _set_address(rt_uint8_t address)
{
usb_devaddr_set(&gd_usb_core, address);
return RT_EOK;
}
static rt_err_t _set_config(rt_uint8_t address)
{
return RT_EOK;
}
static rt_err_t _ep_enable(uep_t ep)
{
RT_ASSERT(ep != RT_NULL);
RT_ASSERT(ep->ep_desc != RT_NULL);
usb_ep_active(&gd_usb_core,
ep->ep_desc->bEndpointAddress,
ep->ep_desc->wMaxPacketSize,
ep->ep_desc->bmAttributes);
return RT_EOK;
}
static rt_err_t _ep_disable(uep_t ep)
{
RT_ASSERT(ep != RT_NULL);
RT_ASSERT(ep->ep_desc != RT_NULL);
usb_ep_deactivate(&gd_usb_core, ep->ep_desc->bEndpointAddress);
return RT_EOK;
}
static rt_ssize_t _ep_read(rt_uint8_t address, void *buffer)
{
rt_size_t size = 0;
RT_ASSERT(buffer != RT_NULL);
return size;
}
static rt_ssize_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
{
usb_ep_outxfer(&gd_usb_core, address, buffer, size);
return size;
}
static rt_ssize_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
{
usb_ep_inxfer(&gd_usb_core, address, buffer, size);
return size;
}
static rt_err_t _ep0_send_status(void)
{
usb_ep_inxfer(&gd_usb_core, 0, NULL, 0);
usb_ctlep_startout(&gd_usb_core);
return RT_EOK;
}
static rt_err_t _suspend(void)
{
return RT_EOK;
}
static rt_err_t _wakeup(void)
{
return RT_EOK;
}
static rt_err_t _init(rt_device_t device)
{
usb_rcu_config();
usb_timer_init();
#ifdef USE_USBHS0
#ifdef USE_USB_FS
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_FULL);
#endif
#ifdef USE_USB_HS
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_HIGH);
#endif
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
#ifdef USE_USB_FS
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_FULL);
#endif
#ifdef USE_USB_HS
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_HIGH);
#endif
#endif /* USE_USBHS1 */
/* configure USB capabilites */
usb_basic_init(&gd_usb_core.bp, &gd_usb_core.regs);
usb_globalint_disable(&gd_usb_core.regs);
/* initailizes the USB core*/
usb_core_init(gd_usb_core.bp, &gd_usb_core.regs);
/* set device disconnect */
usbd_set_connection_state(0);
usb_curmode_set(&gd_usb_core.regs, DEVICE_MODE);
/* initailizes device mode */
usb_devcore_init(&gd_usb_core);
usb_globalint_enable(&gd_usb_core.regs);
/* set device connect */
usbd_set_connection_state(1);
#ifdef USE_USB_HS
#ifdef USE_USBHS0
pllusb_rcu_config(USBHS0);
#endif
#ifdef USE_USBHS1
pllusb_rcu_config(USBHS1);
#endif
#endif /* USE_USB_HS */
usb_intr_config();
return RT_EOK;
}
const static struct udcd_ops _udc_ops = {
_set_address,
_set_config,
_ep_set_stall,
_ep_clear_stall,
_ep_enable,
_ep_disable,
_ep_read_prepare,
_ep_read,
_ep_write,
_ep0_send_status,
_suspend,
_wakeup,
};
int gd_usbd_register(void)
{
rt_memset((void *)&_gd_udc, 0, sizeof(struct udcd));
_gd_udc.parent.type = RT_Device_Class_USBDevice;
_gd_udc.parent.init = _init;
_gd_udc.parent.user_data = NULL;
_gd_udc.ops = &_udc_ops;
/* Register endpoint infomation */
_gd_udc.ep_pool = _ep_pool;
_gd_udc.ep0.id = &_ep_pool[0];
rt_device_register((rt_device_t)&_gd_udc, "usbd", 0);
rt_usb_device_init();
return RT_EOK;
}
INIT_DEVICE_EXPORT(gd_usbd_register);
#ifdef RT_USB_DEVICE_HID
void usbd_hid_send(uint8_t *buffer, uint16_t size)
{
struct hid_s
{
struct rt_device parent;
struct ufunction *func;
uep_t ep_in;
uep_t ep_out;
int status;
rt_uint16_t protocol;
rt_uint8_t report_buf[64];
struct rt_messagequeue hid_mq;
};
udevice_t device = RT_NULL;
uintf_t intf;
ufunction_t func;
struct hid_s *hiddev;
device = rt_usbd_find_device(&_gd_udc);
intf = rt_usbd_find_interface(device, 0, &func);
if (RT_NULL != intf)
{
hiddev = (struct hid_s *)func->user_data;
hiddev->parent.write(&hiddev->parent, 0, buffer, size);
}
}
#endif
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */

315
828ECO/drivers/usb/drv_otghs_host.c

@ -0,0 +1,315 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_otghs_host.h"
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "drv_usb_hw.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
#define OTG_FS_PORT 1
usb_core_driver gd_usb_core;
static struct rt_completion urb_completion;
static volatile rt_bool_t connect_status = RT_FALSE;
void usbh_connect_callback(usb_core_driver *hhcd)
{
uhcd_t hcd = (uhcd_t)hhcd->host.data;
if (!connect_status)
{
connect_status = RT_TRUE;
rt_usbh_root_hub_connect_handler(hcd, OTG_FS_PORT, RT_FALSE);
}
}
void usbh_disconnect_callback(usb_core_driver *hhcd)
{
uhcd_t hcd = (uhcd_t)hhcd->host.data;
if (connect_status)
{
connect_status = RT_FALSE;
rt_usbh_root_hub_disconnect_handler(hcd, OTG_FS_PORT);
}
}
void usbh_hc_notifyurbchange_callback(usb_core_driver *hhcd, uint8_t chnum, usb_urb_state urb_state)
{
rt_completion_done(&urb_completion);
}
static rt_err_t drv_reset_port(rt_uint8_t port)
{
usb_port_reset(&gd_usb_core);
return RT_EOK;
}
static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeout)
{
while (1)
{
uint8_t dir = (pipe->ep.bEndpointAddress & 0x80) >> 7;
if (!connect_status)
{
return -1;
}
rt_completion_init(&urb_completion);
if (dir == 0)
{
if (token == 0)
{
usbh_ctlsetup_send(&gd_usb_core, buffer, pipe->pipe_index);
}
else
{
usbh_data_send(&gd_usb_core, buffer, pipe->pipe_index, nbytes);
}
}
else
{
usbh_data_recev(&gd_usb_core, buffer, pipe->pipe_index, nbytes);
}
rt_completion_wait(&urb_completion, timeout);
rt_thread_mdelay(1);
if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_NOTREADY)
{
if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
{
rt_thread_delay((pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) > 0 ? (pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) : 1);
}
usb_pipe_halt(&gd_usb_core, pipe->pipe_index);
usbh_pipe_create(&gd_usb_core,
pipe->inst->address,
(uint8_t)PORT_SPEED_FULL,
pipe->pipe_index,
pipe->ep.bEndpointAddress,
pipe->ep.bmAttributes,
pipe->ep.wMaxPacketSize);
continue;
}
else if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_STALL)
{
pipe->status = UPIPE_STATUS_STALL;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
return -1;
}
else if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_ERROR)
{
pipe->status = UPIPE_STATUS_ERROR;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
return -1;
}
else if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_DONE)
{
pipe->status = UPIPE_STATUS_OK;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
if (pipe->ep.bEndpointAddress & 0x80)
{
return usbh_xfercount_get(&gd_usb_core, pipe->pipe_index);
}
return nbytes;
}
return -1;
}
}
static rt_uint16_t pipe_index = 0;
static rt_uint8_t drv_get_free_pipe_index()
{
rt_uint8_t idx;
for (idx = 1; idx < 16; idx++)
{
if (!(pipe_index & (0x01 << idx)))
{
pipe_index |= (0x01 << idx);
return (idx - 1);
}
}
return 0xff;
}
static void drv_free_pipe_index(rt_uint8_t index)
{
pipe_index &= ~(0x01 << index);
}
static rt_err_t drv_open_pipe(upipe_t pipe)
{
pipe->pipe_index = drv_get_free_pipe_index();
usbh_pipe_create(&gd_usb_core,
pipe->inst->address,
(uint8_t)PORT_SPEED_FULL,
pipe->pipe_index,
pipe->ep.bEndpointAddress,
pipe->ep.bmAttributes,
pipe->ep.wMaxPacketSize);
/* Set DATA0 PID token*/
if (gd_usb_core.host.pipe[pipe->pipe_index].ep.dir)
{
gd_usb_core.host.pipe[pipe->pipe_index].data_toggle_in = 0;
}
else
{
gd_usb_core.host.pipe[pipe->pipe_index].data_toggle_out = 0;
}
return RT_EOK;
}
static rt_err_t drv_close_pipe(upipe_t pipe)
{
usb_pipe_halt(&gd_usb_core, pipe->pipe_index);
drv_free_pipe_index(pipe->pipe_index);
return RT_EOK;
}
struct uhcd_ops _uhcd_ops = {
drv_reset_port,
drv_pipe_xfer,
drv_open_pipe,
drv_close_pipe,
};
static rt_err_t gd32_hcd_init(rt_device_t device)
{
usb_rcu_config();
usb_timer_init();
/* configure GPIO pin used for switching VBUS power and charge pump I/O */
usb_vbus_config();
uint8_t i = 0U;
#ifdef USE_USBHS0
#ifdef USE_USB_FS
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_FULL);
#endif
#ifdef USE_USB_HS
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_HIGH);
#endif
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
#ifdef USE_USB_FS
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_FULL);
#endif
#ifdef USE_USB_HS
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_HIGH);
#endif
#endif /* USE_USBHS1 */
gd_usb_core.host.connect_status = 0U;
for (i = 0U; i < USBHS_MAX_TX_FIFOS; i++)
{
gd_usb_core.host.pipe[i].err_count = 0U;
gd_usb_core.host.pipe[i].pp_status = PIPE_IDLE;
gd_usb_core.host.backup_xfercount[i] = 0U;
}
gd_usb_core.host.pipe[0].ep.mps = 8U;
usb_basic_init(&gd_usb_core.bp, &gd_usb_core.regs);
usb_globalint_disable(&gd_usb_core.regs);
usb_core_init(gd_usb_core.bp, &gd_usb_core.regs);
#ifndef USE_OTG_MODE
usb_curmode_set(&gd_usb_core.regs, HOST_MODE);
#endif /* USE_OTG_MODE */
usb_host_init(&gd_usb_core);
usb_globalint_enable(&gd_usb_core.regs);
#ifdef USE_USB_HS
#ifdef USE_USBHS0
pllusb_rcu_config(USBHS0);
#elif defined USE_USBHS1
pllusb_rcu_config(USBHS1);
#else
#endif
#endif /* USE_USB_HS */
/* enable interrupts */
usb_intr_config();
return RT_EOK;
}
int gd_usbh_register(void)
{
rt_err_t res = -RT_ERROR;
uhcd_t uhcd = (uhcd_t)rt_malloc(sizeof(struct uhcd));
if (uhcd == RT_NULL)
{
rt_kprintf("uhcd malloc failed\r\n");
return -RT_ERROR;
}
rt_memset((void *)uhcd, 0, sizeof(struct uhcd));
uhcd->parent.type = RT_Device_Class_USBHost;
uhcd->parent.init = gd32_hcd_init;
uhcd->parent.user_data = &gd_usb_core;
uhcd->ops = &_uhcd_ops;
uhcd->num_ports = OTG_FS_PORT;
gd_usb_core.host.data = uhcd;
res = rt_device_register(&uhcd->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
if (res != RT_EOK)
{
rt_kprintf("register usb host failed res = %d\r\n", res);
return -RT_ERROR;
}
rt_usb_host_init("usbh");
return RT_EOK;
}
INIT_DEVICE_EXPORT(gd_usbh_register);
#endif /* BSP_USING_USB && RT_USING_USB_HOST */

440
828ECO/drivers/usb/drv_usb_core.c

@ -0,0 +1,440 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usb_hw.h"
#include "drv_usb_core.h"
#if defined(BSP_USING_USB)
/* local function prototypes ('static') */
static void usb_core_reset(usb_core_regs *usb_regs);
/*!
\brief configures USB parameters
\param[in] udev: pointer to USB core instance
\param[in] usb_periph: USBHSx(x=0,1)
\param[in] usb_speed: USB speed type (full-speed or high-speed)
\param[out] none
\retval none
*/
void usb_para_init(usb_core_driver *udev, uint32_t usb_periph, uint32_t usb_speed)
{
usb_core_basic *usb_basic = &udev->bp;
/* configure USB default transfer mode as FIFO mode */
usb_basic->transfer_mode = (uint8_t)USB_USE_FIFO;
/* USB default speed is full-speed */
usb_basic->core_speed = (uint8_t)USB_SPEED_FULL;
/* USB basic register address setting */
switch (usb_periph)
{
case USBHS0:
usb_basic->base_reg = (uint32_t)USBHS0_REG_BASE;
break;
case USBHS1:
usb_basic->base_reg = (uint32_t)USBHS1_REG_BASE;
break;
default:
break;
}
/* set the host channel numbers */
usb_basic->num_pipe = USBHS_MAX_CHANNEL_COUNT;
/* set the device endpoint numbers */
usb_basic->num_ep = USBHS_MAX_EP_COUNT;
if (USB_SPEED_HIGH == usb_speed)
{
#ifdef USB_EXTERNAL_ULPI_PHY_ENABLED
usb_basic->phy_itf = USB_ULPI_PHY_EXTERNAL;
#endif /* USB_EXTERNAL_ULPI_PHY_ENABLED */
#ifdef USB_EMBEDDED_HS_PHY_ENABLED
usb_basic->phy_itf = USB_EMBEDDED_PHY_HS;
#endif /* USB_EMBEDDED_HS_PHY_ENABLED */
}
else if (USB_SPEED_FULL == usb_speed)
{
#ifdef USB_EMBEDDED_FS_PHY_ENABLED
usb_basic->phy_itf = USB_EMBEDDED_PHY_FS;
#endif /* USB_EMBEDDED_FS_PHY_ENABLED */
}
else
{
/* no operation */
}
#ifdef USB_INTERNAL_DMA_ENABLED
usb_basic->transfer_mode = USB_USE_DMA;
#endif /* USB_INTERNAL_DMA_ENABLED */
usb_basic->sof_enable = (uint8_t)USB_SOF_OUTPUT;
usb_basic->low_power = (uint8_t)USB_LOW_POWER;
#if (1U == LPM_ENABLED)
usb_basic->lpm_enable = 1U;
#endif /* LPM_ENABLED */
}
/*!
\brief configure USB core basic
\param[in] usb_basic: pointer to USB capabilities
\param[in] usb_regs: pointer to USB core registers
\param[out] none
\retval operation status
*/
usb_status usb_basic_init(usb_core_basic *usb_basic, usb_core_regs *usb_regs)
{
/* assign main registers address */
*usb_regs = (usb_core_regs){
.gr = (usb_gr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_CORE),
.hr = (usb_hr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_HOST),
.dr = (usb_dr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_DEV),
.HPCS = (uint32_t *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_PORT),
.PWRCLKCTL = (uint32_t *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_PWRCLKCTL)
};
/* assign device endpoint registers address */
for (uint8_t i = 0U; i < usb_basic->num_ep; i++)
{
usb_regs->er_in[i] = (usb_erin *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_EP_IN + (i * (uint32_t)USB_REG_OFFSET_EP));
usb_regs->er_out[i] = (usb_erout *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_EP_OUT + (i * (uint32_t)USB_REG_OFFSET_EP));
}
/* assign host pipe registers address */
for (uint8_t i = 0U; i < usb_basic->num_pipe; i++)
{
usb_regs->pr[i] = (usb_pr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_CH_INOUT + (i * (uint32_t)USB_REG_OFFSET_CH));
usb_regs->DFIFO[i] = (uint32_t *)(usb_basic->base_reg + (uint32_t)USB_DATA_FIFO_OFFSET + (i * (uint32_t)USB_DATA_FIFO_SIZE));
}
return USB_OK;
}
/*!
\brief initializes the USB controller registers and
prepares the core device mode or host mode operation
\param[in] usb_basic: pointer to USB capabilities
\param[in] usb_regs: pointer to USB core registers
\param[out] none
\retval operation status
*/
usb_status usb_core_init(usb_core_basic usb_basic, usb_core_regs *usb_regs)
{
if (USB_ULPI_PHY_EXTERNAL == usb_basic.phy_itf)
{
usb_regs->gr->GCCFG &= ~GCCFG_PWRON;
usb_regs->gr->GUSBCS &= ~(GUSBCS_EMBPHY_HS | GUSBCS_EMBPHY_FS);
if (usb_basic.sof_enable)
{
usb_regs->gr->GCCFG |= GCCFG_SOFOEN;
}
/* initialize the ULPI interface */
usb_regs->gr->GUSBCS &= ~GUSBCS_ULPIEOI;
#ifdef USBHS_EXTERNAL_VBUS_ENABLED
/* use external VBUS driver */
usb_regs->gr->GUSBCS |= GUSBCS_ULPIEVD;
#else
/* use internal VBUS driver */
usb_regs->gr->GUSBCS &= ~GUSBCS_ULPIEVD;
#endif /* USBHS_EXTERNAL_VBUS_ENABLED */
/* soft reset the core */
usb_core_reset(usb_regs);
}
else if (USB_EMBEDDED_PHY_HS == usb_basic.phy_itf)
{
usb_regs->gr->GUSBCS |= GUSBCS_EMBPHY_HS;
/* soft reset the core */
usb_core_reset(usb_regs);
usb_regs->gr->GCCFG = 0U;
#ifdef VBUS_SENSING_ENABLED
/* active the transceiver and enable VBUS sensing */
usb_regs->gr->GCCFG |= GCCFG_VDEN | GCCFG_PWRON;
#else
#ifdef USE_HOST_MODE
usb_regs->gr->GOTGCS |= GOTGCS_AVOV | GOTGCS_AVOE;
#endif /* USE_HOST_MODE */
#ifdef USE_DEVICE_MODE
usb_regs->gr->GOTGCS |= GOTGCS_BVOV | GOTGCS_BVOE;
#endif /* USE_DEVICE_MODE */
/* active the transceiver */
usb_regs->gr->GCCFG |= GCCFG_PWRON;
#endif /* VBUS_SENSING_ENABLED */
if (usb_basic.sof_enable)
{
usb_regs->gr->GCCFG |= GCCFG_SOFOEN;
}
usb_mdelay(20U);
}
else if (USB_EMBEDDED_PHY_FS == usb_basic.phy_itf)
{
usb_regs->gr->GUSBCS |= GUSBCS_EMBPHY_FS;
/* soft reset the core */
usb_core_reset(usb_regs);
#ifdef VBUS_SENSING_ENABLED
/* active the transceiver and enable VBUS sensing */
usb_regs->gr->GCCFG |= GCCFG_VDEN | GCCFG_PWRON;
#else
#ifdef USE_HOST_MODE
usb_regs->gr->GOTGCS |= GOTGCS_AVOV | GOTGCS_AVOE;
#endif /* USE_HOST_MODE */
#ifdef USE_DEVICE_MODE
usb_regs->gr->GOTGCS |= GOTGCS_BVOV | GOTGCS_BVOE;
#endif /* USE_DEVICE_MODE */
/* active the transceiver */
usb_regs->gr->GCCFG |= GCCFG_PWRON;
#endif /* VBUS_SENSING_ENABLED */
/* enable SOF output */
if (usb_basic.sof_enable)
{
usb_regs->gr->GCCFG |= GCCFG_SOFOEN;
}
usb_mdelay(20U);
}
else
{
/* no operation */
}
if ((uint8_t)USB_USE_DMA == usb_basic.transfer_mode)
{
usb_regs->gr->GAHBCS &= ~GAHBCS_BURST;
usb_regs->gr->GAHBCS |= DMA_INCR8 | GAHBCS_DMAEN;
}
#ifdef USE_OTG_MODE
/* enable USB OTG features */
usb_regs->gr->GUSBCS |= GUSBCS_HNPCEN | GUSBCS_SRPCEN;
/* enable the USB wakeup and suspend interrupts */
usb_regs->gr->GINTF = 0xBFFFFFFFU;
usb_regs->gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE |
GINTEN_OTGIE | GINTEN_SESIE | GINTEN_IDPSCIE;
#endif /* USE_OTG_MODE */
return USB_OK;
}
/*!
\brief write a packet into the TX FIFO associated with the endpoint
\param[in] usb_regs: pointer to USB core registers
\param[in] src_buf: pointer to source buffer
\param[in] fifo_num: FIFO number which is in (0..5)
\param[in] byte_count: packet byte count
\param[out] none
\retval operation status
*/
usb_status usb_txfifo_write(usb_core_regs *usb_regs,
uint8_t *src_buf,
uint8_t fifo_num,
uint16_t byte_count)
{
uint32_t word_count = (byte_count + 3U) / 4U;
__IO uint32_t *fifo = usb_regs->DFIFO[fifo_num];
while (word_count-- > 0U)
{
*fifo = *((__IO uint32_t *)src_buf);
src_buf += 4U;
}
return USB_OK;
}
/*!
\brief read a packet from the Rx FIFO associated with the endpoint
\param[in] usb_regs: pointer to USB core registers
\param[in] dest_buf: pointer to destination buffer
\param[in] byte_count: packet byte count
\param[out] none
\retval void type pointer
*/
void *usb_rxfifo_read(usb_core_regs *usb_regs, uint8_t *dest_buf, uint16_t byte_count)
{
__IO uint32_t word_count = (byte_count + 3U) / 4U;
__IO uint32_t *fifo = usb_regs->DFIFO[0];
while (word_count-- > 0U)
{
*(__IO uint32_t *)dest_buf = *fifo;
dest_buf += 4U;
}
return ((void *)dest_buf);
}
/*!
\brief flush a TX FIFO or all TX FIFOs
\param[in] usb_regs: pointer to USB core registers
\param[in] fifo_num: FIFO number which is in (0..5)
\param[out] none
\retval operation status
*/
usb_status usb_txfifo_flush(usb_core_regs *usb_regs, uint8_t fifo_num)
{
usb_regs->gr->GRSTCTL = ((uint32_t)fifo_num << 6) | GRSTCTL_TXFF;
/* wait for TX FIFO flush bit is set */
while (usb_regs->gr->GRSTCTL & GRSTCTL_TXFF)
{
/* no operation */
}
/* wait for 3 PHY clocks*/
usb_udelay(3U);
return USB_OK;
}
/*!
\brief flush the entire RX FIFO
\param[in] usb_regs: pointer to USB core registers
\param[out] none
\retval operation status
*/
usb_status usb_rxfifo_flush(usb_core_regs *usb_regs)
{
usb_regs->gr->GRSTCTL = GRSTCTL_RXFF;
/* wait for RX FIFO flush bit is set */
while (usb_regs->gr->GRSTCTL & GRSTCTL_RXFF)
{
/* no operation */
}
/* wait for 3 PHY clocks */
usb_udelay(3U);
return USB_OK;
}
/*!
\brief set endpoint or channel TX FIFO size
\param[in] usb_regs: pointer to USB core registers
\param[in] fifo: TX FIFO number
\param[in] size: assigned TX FIFO size
\param[out] none
\retval none
*/
void usb_set_txfifo(usb_core_regs *usb_regs, uint8_t fifo, uint16_t size)
{
uint32_t tx_offset = usb_regs->gr->GRFLEN;
if (0U == fifo)
{
usb_regs->gr->DIEP0TFLEN_HNPTFLEN = ((uint32_t)size << 16) | tx_offset;
}
else
{
tx_offset += (usb_regs->gr->DIEP0TFLEN_HNPTFLEN) >> 16;
for (uint8_t i = 0U; i < (fifo - 1U); i++)
{
tx_offset += (usb_regs->gr->DIEPTFLEN[i] >> 16);
}
usb_regs->gr->DIEPTFLEN[fifo - 1U] = ((uint32_t)size << 16) | tx_offset;
}
}
/*!
\brief set USB current mode
\param[in] usb_regs: pointer to USB core registers
\param[in] mode: USB current mode
\param[out] none
\retval none
*/
void usb_curmode_set(usb_core_regs *usb_regs, uint8_t mode)
{
usb_regs->gr->GUSBCS &= ~(GUSBCS_FDM | GUSBCS_FHM);
if (DEVICE_MODE == mode)
{
usb_regs->gr->GUSBCS |= GUSBCS_FDM;
}
else if (HOST_MODE == mode)
{
usb_regs->gr->GUSBCS |= GUSBCS_FHM;
}
else
{
/* OTG mode and other mode can not be here! */
}
}
/*!
\brief configure USB core to soft reset
\param[in] usb_regs: pointer to USB core registers
\param[out] none
\retval none
*/
static void usb_core_reset(usb_core_regs *usb_regs)
{
/* enable core soft reset */
usb_regs->gr->GRSTCTL |= GRSTCTL_CSRST;
/* wait for the core to be soft reset */
while (usb_regs->gr->GRSTCTL & GRSTCTL_CSRST)
{
/* no operation */
}
/* wait for additional 3 PHY clocks */
usb_udelay(3U);
}
/*!
\brief active USB core clock
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
void usb_clock_active(usb_core_driver *udev)
{
if (udev->bp.low_power)
{
if (udev->regs.dr->DSTAT & DSTAT_SPST)
{
/* un-gate USB Core clock */
*udev->regs.PWRCLKCTL &= ~(PWRCLKCTL_SHCLK | PWRCLKCTL_SUCLK);
}
}
}
#endif /* BSP_USING_USB */

755
828ECO/drivers/usb/drv_usb_dev.c

@ -0,0 +1,755 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usb_hw.h"
#include "drv_usb_dev.h"
#include <stdio.h>
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE)
/* endpoint 0 max packet length */
static const uint8_t EP0_MAXLEN[4] = {
[DSTAT_EM_HS_PHY_30MHZ_60MHZ] = EP0MPL_64,
[DSTAT_EM_FS_PHY_30MHZ_60MHZ] = EP0MPL_64,
[DSTAT_EM_FS_PHY_48MHZ] = EP0MPL_64,
[DSTAT_EM_LS_PHY_6MHZ] = EP0MPL_8
};
/* USB endpoint TX FIFO size */
static uint16_t USBHS_TX_FIFO_SIZE[USBHS_MAX_EP_COUNT] = {
(uint16_t)TX0_FIFO_SIZE,
(uint16_t)TX1_FIFO_SIZE,
(uint16_t)TX2_FIFO_SIZE,
(uint16_t)TX3_FIFO_SIZE,
(uint16_t)TX4_FIFO_SIZE,
(uint16_t)TX5_FIFO_SIZE,
(uint16_t)TX6_FIFO_SIZE,
(uint16_t)TX7_FIFO_SIZE,
};
/*!
\brief initialize USB core registers for device mode
\param[in] udev: pointer to USB device
\param[out] none
\retval operation status
*/
usb_status usb_devcore_init(usb_core_driver *udev)
{
uint8_t i = 0U;
/* restart the PHY clock (maybe don't need to...) */
*udev->regs.PWRCLKCTL = 0U;
/* configure periodic frame interval to default value */
udev->regs.dr->DCFG &= ~DCFG_EOPFT;
udev->regs.dr->DCFG |= FRAME_INTERVAL_80;
udev->regs.dr->DCFG &= ~DCFG_DS;
if (USB_EMBEDDED_PHY_HS == udev->bp.phy_itf)
{
udev->regs.dr->DCFG |= USB_SPEED_INP_HIGH;
}
else if (USB_EMBEDDED_PHY_FS == udev->bp.phy_itf)
{
udev->regs.dr->DCFG |= USB_SPEED_INP_FULL;
}
else
{
/* no operation */
}
/* set RX FIFO size */
usb_set_rxfifo(&udev->regs, (uint16_t)RX_FIFO_SIZE);
/* set endpoint 0 to 3's TX FIFO length and RAM address */
for (i = 0U; i < USBHS_MAX_EP_COUNT; i++)
{
usb_set_txfifo(&udev->regs, i, USBHS_TX_FIFO_SIZE[i]);
}
/* make sure all FIFOs are flushed */
/* flush all TX FIFOs */
(void)usb_txfifo_flush(&udev->regs, 0x10U);
/* flush entire RX FIFO */
(void)usb_rxfifo_flush(&udev->regs);
/* clear all pending device interrupts */
udev->regs.dr->DIEPINTEN = 0U;
udev->regs.dr->DOEPINTEN = 0U;
udev->regs.dr->DAEPINT = 0xFFFFFFFFU;
udev->regs.dr->DAEPINTEN = 0U;
/* configure all IN/OUT endpoints */
for (i = 0U; i < udev->bp.num_ep; i++)
{
if (udev->regs.er_in[i]->DIEPCTL & DEPCTL_EPEN)
{
udev->regs.er_in[i]->DIEPCTL |= DEPCTL_EPD | DEPCTL_SNAK;
}
else
{
udev->regs.er_in[i]->DIEPCTL = 0U;
}
/* set IN endpoint transfer length to 0 */
udev->regs.er_in[i]->DIEPLEN = 0U;
/* clear all pending IN endpoint interrupts */
udev->regs.er_in[i]->DIEPINTF = 0xFFU;
if (udev->regs.er_out[i]->DOEPCTL & DEPCTL_EPEN)
{
udev->regs.er_out[i]->DOEPCTL |= DEPCTL_EPD | DEPCTL_SNAK;
}
else
{
udev->regs.er_out[i]->DOEPCTL = 0U;
}
/* set OUT endpoint transfer length to 0 */
udev->regs.er_out[i]->DOEPLEN = 0U;
/* clear all pending OUT endpoint interrupts */
udev->regs.er_out[i]->DOEPINTF = 0xFFU;
}
udev->regs.dr->DIEPINTEN |= DIEPINTEN_EPTXFUDEN;
(void)usb_devint_enable(udev);
/* configure LPM function */
if (1U == udev->bp.lpm_enable)
{
udev->dev.pm.lpm_state = LPM_L0;
udev->regs.gr->GLPMCFG = GLPMCFG_LPMEN | GLPMCFG_ACKLPM | GLPMCFG_BESLEN;
}
return USB_OK;
}
/*!
\brief enable the USB device mode interrupts
\param[in] udev: pointer to USB device
\param[out] none
\retval operation status
*/
usb_status usb_devint_enable(usb_core_driver *udev)
{
/* clear any pending USB OTG interrupts */
udev->regs.gr->GOTGINTF = 0xFFFFFFFFU;
/* clear any pending interrupts */
udev->regs.gr->GINTF = 0xBFFFFFFFU;
/* enable the USB wakeup and suspend interrupts */
udev->regs.gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE;
/* enable device_mode-related interrupts */
if ((uint8_t)USB_USE_FIFO == udev->bp.transfer_mode)
{
udev->regs.gr->GINTEN |= GINTEN_RXFNEIE;
}
udev->regs.gr->GINTEN |= GINTEN_RSTIE | GINTEN_ENUMFIE | GINTEN_IEPIE |
GINTEN_OEPIE | GINTEN_SOFIE | GINTEN_ISOONCIE | GINTEN_ISOINCIE;
#ifdef VBUS_SENSING_ENABLED
udev->regs.gr->GINTEN |= GINTEN_SESIE | GINTEN_OTGIE;
#endif /* VBUS_SENSING_ENABLED */
if (1U == udev->bp.lpm_enable)
{
udev->regs.gr->GINTEN |= GINTEN_LPMIE;
}
return USB_OK;
}
/*!
\brief active the USB endpoint0 transaction
\param[in] udev: pointer to USB device
\param[in] transc: the USB endpoint0 transaction
\param[out] none
\retval operation status
*/
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc)
{
__IO uint32_t *reg_addr = NULL;
uint32_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES;
/* get the endpoint number */
uint8_t ep_num = transc->ep_addr.num;
if (ep_num)
{
/* not endpoint 0 */
return USB_FAIL;
}
if (transc->ep_addr.dir)
{
reg_addr = &udev->regs.er_in[0]->DIEPCTL;
}
else
{
reg_addr = &udev->regs.er_out[0]->DOEPCTL;
}
/* endpoint 0 is activated after USB clock is enabled */
*reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);
/* set endpoint 0 maximum packet length */
*reg_addr |= EP0_MAXLEN[enum_speed];
/* activate endpoint */
*reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;
return USB_OK;
}
/*!
\brief active the USB transaction
\param[in] udev: pointer to USB device
\param[in] transc: the USB transaction
\param[out] none
\retval status
*/
usb_status usb_ep_active(usb_core_driver *udev, uint8_t ep_addr, uint8_t ep_mps, uint8_t ep_attr)
{
__IO uint32_t *reg_addr = NULL;
uint32_t epinten = 0U;
uint32_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES;
usb_transc *transc = NULL;
/* get the endpoint number */
uint8_t ep_num = EP_ID(ep_addr);
/* enable endpoint interrupt number */
if (EP_DIR(ep_addr))
{
reg_addr = &udev->regs.er_in[ep_num]->DIEPCTL;
epinten = 1U << ep_num;
transc = &udev->dev.transc_in[ep_num];
}
else
{
reg_addr = &udev->regs.er_out[ep_num]->DOEPCTL;
epinten = 1U << (16U + ep_num);
transc = &udev->dev.transc_out[ep_num];
}
*transc = (usb_transc){ 0 };
transc->max_len = ep_mps;
transc->ep_type = ep_attr & USB_EPTYPE_MASK;
/* if the endpoint is not active, need change the endpoint control register */
if (!(*reg_addr & DEPCTL_EPACT))
{
*reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);
/* set endpoint maximum packet length */
if (0U == ep_num)
{
*reg_addr |= EP0_MAXLEN[enum_speed];
}
else
{
*reg_addr |= transc->max_len;
}
/* activate endpoint */
*reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;
}
#ifdef USB_DEDICATED_EP1_ENABLED
if (1U == ep_num)
{
udev->regs.dr->DEP1INTEN |= epinten;
}
else
#endif
{
/* enable the interrupts for this endpoint */
udev->regs.dr->DAEPINTEN |= epinten;
}
return USB_OK;
}
/*!
\brief deactivate the USB transaction
\param[in] udev: pointer to USB device
\param[in] transc: the USB transaction
\param[out] none
\retval status
*/
usb_status usb_ep_deactivate(usb_core_driver *udev, uint8_t ep_addr)
{
uint32_t epinten = 0U;
uint8_t ep_num = EP_ID(ep_addr);
/* disable endpoint interrupt number */
if (EP_DIR(ep_addr))
{
epinten = 1U << ep_num;
udev->regs.er_in[ep_num]->DIEPCTL &= ~DEPCTL_EPACT;
}
else
{
epinten = 1U << (ep_num + 16U);
udev->regs.er_out[ep_num]->DOEPCTL &= ~DEPCTL_EPACT;
}
#ifdef USB_DEDICATED_EP1_ENABLED
if (1U == ep_num)
{
udev->regs.dr->DEP1INTEN &= ~epinten;
}
else
#endif
{
/* disable the interrupts for this endpoint */
udev->regs.dr->DAEPINTEN &= ~epinten;
}
return USB_OK;
}
/*!
\brief configure USB transaction to start IN transfer
\param[in] udev: pointer to USB device
\param[in] transc: the USB IN transaction
\param[out] none
\retval operation status
*/
usb_status usb_ep_inxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count)
{
usb_status status = USB_OK;
uint8_t ep_num = EP_ID(ep_addr);
__IO uint32_t epctl = udev->regs.er_in[ep_num]->DIEPCTL;
__IO uint32_t eplen = udev->regs.er_in[ep_num]->DIEPLEN;
usb_transc *transc = &udev->dev.transc_in[ep_num];
eplen &= ~(DEPLEN_TLEN | DEPLEN_PCNT);
transc->xfer_len = count;
transc->xfer_buf = buf;
transc->xfer_count = 0U;
/* zero length packet or endpoint 0 */
if (0U == count)
{
/* set transfer packet count to 1 */
eplen |= 1U << 19;
}
else
{
/* set transfer packet count */
if (0U == ep_num)
{
transc->xfer_len = USB_MIN(count, transc->max_len);
eplen |= 1U << 19;
}
else
{
eplen |= ((count - 1 + transc->max_len) / transc->max_len) << 19;
}
/* set endpoint transfer length */
eplen |= count;
if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type)
{
eplen |= DIEPLEN_MCNT & (1U << 29);
}
}
udev->regs.er_in[ep_num]->DIEPLEN = eplen;
if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type)
{
if (((udev->regs.dr->DSTAT & DSTAT_FNRSOF) >> 8) & 0x01U)
{
epctl |= DEPCTL_SEVNFRM;
}
else
{
epctl |= DEPCTL_SODDFRM;
}
}
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode)
{
udev->regs.er_in[ep_num]->DIEPDMAADDR = transc->dma_addr;
}
/* enable the endpoint and clear the NAK */
epctl |= DEPCTL_CNAK | DEPCTL_EPEN;
udev->regs.er_in[ep_num]->DIEPCTL = epctl;
if ((uint8_t)USB_USE_FIFO == udev->bp.transfer_mode)
{
if ((uint8_t)USB_EPTYPE_ISOC != transc->ep_type)
{
/* enable the TX FIFO empty interrupt for this endpoint */
if (count > 0U)
{
udev->regs.dr->DIEPFEINTEN |= 1U << ep_num;
}
}
else
{
(void)usb_txfifo_write(&udev->regs, transc->xfer_buf, ep_num, (uint16_t)transc->xfer_len);
}
}
return status;
}
/*!
\brief configure USB transaction to start OUT transfer
\param[in] udev: pointer to USB device
\param[in] transc: the USB OUT transaction
\param[out] none
\retval status
*/
usb_status usb_ep_outxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count)
{
usb_status status = USB_OK;
uint8_t ep_num = EP_ID(ep_addr);
uint32_t epctl = udev->regs.er_out[ep_num]->DOEPCTL;
uint32_t eplen = udev->regs.er_out[ep_num]->DOEPLEN;
usb_transc *transc = &udev->dev.transc_out[ep_num];
transc->xfer_buf = buf;
transc->xfer_len = count;
eplen &= ~(DEPLEN_TLEN | DEPLEN_PCNT);
/* zero length packet or endpoint 0 */
if ((0U == count) || (0U == ep_num))
{
/* set the transfer length to max packet size */
eplen |= transc->max_len;
/* set the transfer packet count to 1 */
eplen |= 1U << 19;
}
else
{
/* configure the transfer size and packet count as follows:
* pktcnt = N
* xfersize = N * maxpacket
*/
uint32_t packet_count = (count + transc->max_len - 1) / transc->max_len;
eplen |= packet_count << 19;
eplen |= packet_count * transc->max_len;
}
udev->regs.er_out[ep_num]->DOEPLEN = eplen;
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode)
{
udev->regs.er_out[ep_num]->DOEPDMAADDR = transc->dma_addr;
}
if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type)
{
if (transc->frame_num)
{
epctl |= DEPCTL_SD1PID;
}
else
{
epctl |= DEPCTL_SD0PID;
}
}
/* enable the endpoint and clear the NAK */
epctl |= DEPCTL_EPEN | DEPCTL_CNAK;
udev->regs.er_out[ep_num]->DOEPCTL = epctl;
return status;
}
/*!
\brief set the USB transaction STALL status
\param[in] udev: pointer to USB device
\param[in] transc: the USB transaction
\param[out] none
\retval status
*/
usb_status usb_ep_stall(usb_core_driver *udev, uint8_t ep_addr)
{
__IO uint32_t *reg_addr = NULL;
uint8_t ep_num = EP_ID(ep_addr);
if (EP_DIR(ep_addr))
{
reg_addr = &(udev->regs.er_in[ep_num]->DIEPCTL);
/* set the endpoint disable bit */
if (*reg_addr & DEPCTL_EPEN)
{
*reg_addr |= DEPCTL_EPD;
}
}
else
{
/* set the endpoint STALL bit */
reg_addr = &(udev->regs.er_out[ep_num]->DOEPCTL);
}
/* set the endpoint STALL bit */
*reg_addr |= DEPCTL_STALL;
return USB_OK;
}
/*!
\brief clear the USB transaction STALL status
\param[in] udev: pointer to USB device
\param[in] transc: the USB transaction
\param[out] none
\retval operation status
*/
usb_status usb_ep_clrstall(usb_core_driver *udev, uint8_t ep_addr)
{
__IO uint32_t *reg_addr = NULL;
uint32_t ep_type = 0U;
uint8_t ep_num = EP_ID(ep_addr);
if (EP_DIR(ep_addr))
{
reg_addr = &(udev->regs.er_in[ep_num]->DIEPCTL);
}
else
{
reg_addr = &(udev->regs.er_out[ep_num]->DOEPCTL);
}
/* clear the endpoint STALL bit */
*reg_addr &= ~DEPCTL_STALL;
ep_type = (DEPCTL_EPTYPE & *reg_addr) >> 18;
/* reset data PID of the periodic endpoints */
if (((uint8_t)USB_EPTYPE_INTR == ep_type) || ((uint8_t)USB_EPTYPE_BULK == ep_type))
{
*reg_addr |= DEPCTL_SD0PID;
}
return USB_OK;
}
/*!
\brief read device IN endpoint interrupt flag register
\param[in] udev: pointer to USB device
\param[in] ep_num: endpoint number
\param[out] none
\retval interrupt value
*/
uint32_t usb_iepintr_read(usb_core_driver *udev, uint8_t ep_num)
{
__IO uint32_t value = 0U;
uint32_t fifoemptymask, commonintmask;
commonintmask = udev->regs.dr->DIEPINTEN;
fifoemptymask = udev->regs.dr->DIEPFEINTEN;
/* check FIFO empty interrupt enable bit */
commonintmask |= ((fifoemptymask >> ep_num) & 0x1U) << 7;
value = udev->regs.er_in[ep_num]->DIEPINTF & commonintmask;
return value;
}
/*!
\brief configures OUT endpoint 0 to receive SETUP packets
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
void usb_ctlep_startout(usb_core_driver *udev)
{
/* set OUT endpoint 0 receive length to 24 bytes, 1 packet and 3 SETUP packets */
udev->regs.er_out[0]->DOEPLEN = DOEP0_TLEN(8U * 3U) | DOEP0_PCNT(1U) | DOEP0_STPCNT(3U);
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode)
{
udev->regs.er_out[0]->DOEPDMAADDR = (uint32_t)&udev->dev.control.req;
/* endpoint enable */
udev->regs.er_out[0]->DOEPCTL |= DEPCTL_EPACT | DEPCTL_EPEN;
}
}
/*!
\brief active remote wakeup signaling
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
void usb_rwkup_active(usb_core_driver *udev)
{
if (udev->dev.pm.dev_remote_wakeup)
{
if (udev->regs.dr->DSTAT & DSTAT_SPST)
{
if (udev->bp.low_power)
{
/* ungate USB core clock */
*udev->regs.PWRCLKCTL &= ~(PWRCLKCTL_SHCLK | PWRCLKCTL_SUCLK);
}
/* active remote wakeup signaling */
udev->regs.dr->DCTL |= DCTL_RWKUP;
usb_mdelay(5U);
udev->regs.dr->DCTL &= ~DCTL_RWKUP;
}
}
}
/*!
\brief USB device suspend
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
void usb_dev_suspend(usb_core_driver *udev)
{
__IO uint32_t devstat = udev->regs.dr->DSTAT;
if ((devstat & DSTAT_SPST) && (udev->bp.low_power))
{
/* switch-off the USB clocks */
*udev->regs.PWRCLKCTL |= PWRCLKCTL_SHCLK;
/* enter DEEP_SLEEP mode with LDO in low power mode */
pmu_to_deepsleepmode(WFI_CMD);
}
}
/*!
\brief stop the device and clean up FIFOs
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
void usb_dev_stop(usb_core_driver *udev)
{
uint32_t i;
udev->dev.cur_status = 1U;
/* clear all interrupt flag and enable bits */
for (i = 0U; i < udev->bp.num_ep; i++)
{
udev->regs.er_in[i]->DIEPINTF = 0xFFU;
udev->regs.er_out[i]->DOEPINTF = 0xFFU;
}
udev->regs.dr->DIEPINTEN = 0U;
udev->regs.dr->DOEPINTEN = 0U;
udev->regs.dr->DAEPINTEN = 0U;
udev->regs.dr->DAEPINT = 0xFFFFFFFFU;
/* flush the FIFO */
(void)usb_rxfifo_flush(&udev->regs);
(void)usb_txfifo_flush(&udev->regs, 0x10U);
}
/*!
\brief usb battery charging detect operation
\param[in] udev: pointer to USB device instance
\param[out] none
\retval bcd type
*/
bcd_type usbd_bcd_detect(usb_core_driver *udev)
{
udev->regs.gr->GCCFG |= GCCFG_DCDEN;
usb_mdelay(1000U);
if (0U == (udev->regs.gr->GCCFG & GCCFG_DCDF))
{
udev->regs.gr->GCCFG &= ~GCCFG_DCDEN;
return BCD_ERROR;
}
udev->regs.gr->GCCFG &= ~GCCFG_DCDEN;
usb_mdelay(20U);
udev->regs.gr->GCCFG |= GCCFG_PEMEN;
usb_mdelay(50U);
if (udev->regs.gr->GCCFG & GCCFG_PDF)
{
udev->regs.gr->GCCFG &= ~GCCFG_PEMEN;
usb_mdelay(20U);
udev->regs.gr->GCCFG |= GCCFG_SDMEN;
usb_mdelay(50U);
if (udev->regs.gr->GCCFG & GCCFG_SDF)
{
udev->regs.gr->GCCFG &= ~GCCFG_SDMEN;
usb_mdelay(20U);
return BCD_DCP;
}
else
{
udev->regs.gr->GCCFG &= ~GCCFG_SDMEN;
usb_mdelay(20U);
return BCD_CDP;
}
}
else if (udev->regs.gr->GCCFG & GCCFG_PS2F)
{
udev->regs.gr->GCCFG &= ~GCCFG_PEMEN;
usb_mdelay(20U);
return BCD_PS2;
}
else
{
udev->regs.gr->GCCFG &= ~GCCFG_PEMEN;
usb_mdelay(20U);
return BCD_SDP;
}
}
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */

448
828ECO/drivers/usb/drv_usb_host.c

@ -0,0 +1,448 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usb_hw.h"
#include "drv_usb_host.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
const uint32_t PIPE_DPID[2] = {
PIPE_DPID_DATA0,
PIPE_DPID_DATA1
};
/*!
\brief initializes USB core for host mode
\param[in] udev: pointer to selected USB host
\param[out] none
\retval operation status
*/
usb_status usb_host_init(usb_core_driver *udev)
{
uint32_t i = 0U, inten = 0U;
uint32_t nptxfifolen = 0U;
uint32_t ptxfifolen = 0U;
/* restart the PHY Clock */
*udev->regs.PWRCLKCTL = 0U;
/* support HS, FS and LS */
udev->regs.hr->HCTL &= ~HCTL_SPDFSLS;
/* set RX FIFO size */
udev->regs.gr->GRFLEN = USB_RX_FIFO_SIZE;
/* set non-periodic TX FIFO size and address */
nptxfifolen |= USB_RX_FIFO_SIZE;
nptxfifolen |= USB_HTX_NPFIFO_SIZE << 16;
udev->regs.gr->DIEP0TFLEN_HNPTFLEN = nptxfifolen;
/* set periodic TX FIFO size and address */
ptxfifolen |= USB_RX_FIFO_SIZE + USB_HTX_PFIFO_SIZE;
ptxfifolen |= USB_HTX_PFIFO_SIZE << 16;
udev->regs.gr->HPTFLEN = ptxfifolen;
#ifdef USE_OTG_MODE
/* clear host set HNP enable in the usb_otg control register */
udev->regs.gr->GOTGCS &= ~GOTGCS_HHNPEN;
#endif /* USE_OTG_MODE */
/* make sure the FIFOs are flushed */
/* flush all TX FIFOs in device or host mode */
usb_txfifo_flush(&udev->regs, 0x10U);
/* flush the entire RX FIFO */
usb_rxfifo_flush(&udev->regs);
/* disable all interrupts */
udev->regs.gr->GINTEN = 0U;
/* clear any pending USB OTG interrupts */
udev->regs.gr->GOTGINTF = 0xFFFFFFFFU;
/* enable the USB wakeup and suspend interrupts */
udev->regs.gr->GINTF = 0xBFFFFFFFU;
/* clear all pending host channel interrupts */
for (i = 0U; i < udev->bp.num_pipe; i++)
{
udev->regs.pr[i]->HCHINTF = 0xFFFFFFFFU;
udev->regs.pr[i]->HCHINTEN = 0U;
}
#ifndef USE_OTG_MODE
usb_portvbus_switch(udev, 1U);
#endif /* USE_OTG_MODE */
udev->regs.gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE;
/* enable host_mode-related interrupts */
if (USB_USE_FIFO == udev->bp.transfer_mode)
{
inten = GINTEN_RXFNEIE;
}
/* configure USBHS interrupts */
inten |= GINTEN_HPIE | GINTEN_HCIE | GINTEN_ISOINCIE;
udev->regs.gr->GINTEN |= inten;
inten = GINTEN_DISCIE | GINTEN_SOFIE;
udev->regs.gr->GINTEN &= ~inten;
return USB_OK;
}
/*!
\brief control the VBUS to power
\param[in] udev: pointer to selected USB host
\param[in] state: VBUS state
\param[out] none
\retval none
*/
void usb_portvbus_switch(usb_core_driver *udev, uint8_t state)
{
uint32_t port = 0U;
/* enable or disable the external charge pump */
usb_vbus_drive(state);
/* turn on the host port power. */
port = usb_port_read(udev);
if ((!(port & HPCS_PP)) && (1U == state))
{
port |= HPCS_PP;
}
if ((port & HPCS_PP) && (0U == state))
{
port &= ~HPCS_PP;
}
*udev->regs.HPCS = port;
usb_mdelay(200U);
}
/*!
\brief reset host port
\param[in] udev: pointer to USB device
\param[out] none
\retval operation status
*/
uint32_t usb_port_reset(usb_core_driver *udev)
{
__IO uint32_t port = usb_port_read(udev);
*udev->regs.HPCS = port | HPCS_PRST;
usb_mdelay(20U); /* see note */
*udev->regs.HPCS = port & ~HPCS_PRST;
usb_mdelay(20U);
return 1U;
}
/*!
\brief initialize host pipe
\param[in] udev: pointer to USB device
\param[in] pipe_num: host pipe number which is in (0..7)
\param[out] none
\retval operation status
*/
usb_status usb_pipe_init(usb_core_driver *udev, uint8_t pipe_num)
{
usb_status status = USB_OK;
__IO uint32_t pp_ctl = 0U;
__IO uint32_t pp_inten = HCHINTEN_TFIE;
usb_pipe *pp = &udev->host.pipe[pipe_num];
/* clear old interrupt conditions for this host channel */
udev->regs.pr[pipe_num]->HCHINTF = 0xFFFFFFFFU;
if (USB_USE_DMA == udev->bp.transfer_mode)
{
pp_inten |= HCHINTEN_DMAERIE;
}
if (pp->ep.dir)
{
pp_inten |= HCHINTEN_BBERIE;
}
/* enable channel interrupts required for this transfer */
switch (pp->ep.type)
{
case USB_EPTYPE_CTRL:
case USB_EPTYPE_BULK:
pp_inten |= HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE | HCHINTEN_NAKIE;
if (!pp->ep.dir)
{
if (PORT_SPEED_HIGH == pp->dev_speed)
{
pp_inten |= HCHINTEN_NYETIE;
pp_inten |= HCHINTEN_ACKIE;
}
}
break;
case USB_EPTYPE_INTR:
pp_inten |= HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE | HCHINTEN_NAKIE | HCHINTEN_REQOVRIE;
break;
case USB_EPTYPE_ISOC:
pp_inten |= HCHINTEN_REQOVRIE | HCHINTEN_ACKIE;
if (pp->ep.dir)
{
pp_inten |= HCHINTEN_USBERIE;
}
break;
default:
break;
}
udev->regs.pr[pipe_num]->HCHINTEN = pp_inten;
/* enable the top level host channel interrupt */
udev->regs.hr->HACHINTEN |= 1U << pipe_num;
/* make sure host channel interrupts are enabled */
udev->regs.gr->GINTEN |= GINTEN_HCIE;
/* program the host channel control register */
pp_ctl |= PIPE_CTL_DAR(pp->dev_addr);
pp_ctl |= PIPE_CTL_EPNUM(pp->ep.num);
pp_ctl |= PIPE_CTL_EPDIR(pp->ep.dir);
pp_ctl |= PIPE_CTL_EPTYPE(pp->ep.type);
pp_ctl |= PIPE_CTL_LSD(PORT_SPEED_LOW == pp->dev_speed);
pp_ctl |= pp->ep.mps;
pp_ctl |= ((uint32_t)(USB_EPTYPE_INTR == pp->ep.type) << 29) & HCHCTL_ODDFRM;
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl;
return status;
}
/*!
\brief prepare host channel for transferring packets
\param[in] udev: pointer to USB device
\param[in] pipe_num: host pipe number which is in (0..7)
\param[out] none
\retval operation status
*/
usb_status usb_pipe_xfer(usb_core_driver *udev, uint8_t pipe_num)
{
usb_status status = USB_OK;
uint16_t dword_len = 0U;
uint16_t packet_count = 0U;
__IO uint32_t pp_ctl = 0U;
usb_pipe *pp = &udev->host.pipe[pipe_num];
uint16_t max_packet_len = pp->ep.mps;
/* compute the expected number of packets associated to the transfer */
if (pp->xfer_len > 0U)
{
packet_count = (uint16_t)((pp->xfer_len + max_packet_len - 1U) / max_packet_len);
if (packet_count > HC_MAX_PACKET_COUNT)
{
packet_count = HC_MAX_PACKET_COUNT;
pp->xfer_len = (uint16_t)(packet_count * max_packet_len);
}
}
else
{
packet_count = 1U;
}
if (pp->ep.dir)
{
pp->xfer_len = (uint16_t)(packet_count * max_packet_len);
}
/* initialize the host channel transfer information */
udev->regs.pr[pipe_num]->HCHLEN = pp->xfer_len | pp->DPID | PIPE_XFER_PCNT(packet_count);
if (USB_USE_DMA == udev->bp.transfer_mode)
{
udev->regs.pr[pipe_num]->HCHDMAADDR = (unsigned int)pp->xfer_buf;
}
pp_ctl = udev->regs.pr[pipe_num]->HCHCTL;
if (usb_frame_even(udev))
{
pp_ctl |= HCHCTL_ODDFRM;
}
else
{
pp_ctl &= ~HCHCTL_ODDFRM;
}
/* set host channel enabled */
pp_ctl |= HCHCTL_CEN;
pp_ctl &= ~HCHCTL_CDIS;
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl;
if (USB_USE_FIFO == udev->bp.transfer_mode)
{
if ((0U == pp->ep.dir) && (pp->xfer_len > 0U))
{
switch (pp->ep.type)
{
/* non-periodic transfer */
case USB_EPTYPE_CTRL:
case USB_EPTYPE_BULK:
dword_len = (uint16_t)((pp->xfer_len + 3U) / 4U);
/* check if there is enough space in FIFO space */
if (dword_len > (udev->regs.gr->HNPTFQSTAT & HNPTFQSTAT_NPTXFS))
{
/* need to process data in nptxfempty interrupt */
udev->regs.gr->GINTEN |= GINTEN_NPTXFEIE;
}
break;
/* periodic transfer */
case USB_EPTYPE_INTR:
case USB_EPTYPE_ISOC:
dword_len = (uint16_t)((pp->xfer_len + 3U) / 4U);
/* check if there is enough space in FIFO space */
if (dword_len > (udev->regs.hr->HPTFQSTAT & HPTFQSTAT_PTXFS))
{
/* need to process data in ptxfempty interrupt */
udev->regs.gr->GINTEN |= GINTEN_PTXFEIE;
}
break;
default:
break;
}
/* write packet into the TX FIFO */
usb_txfifo_write(&udev->regs, pp->xfer_buf, pipe_num, (uint16_t)pp->xfer_len);
}
}
return status;
}
/*!
\brief halt pipe
\param[in] udev: pointer to USB device
\param[in] pipe_num: host pipe number which is in (0..7)
\param[out] none
\retval operation status
*/
usb_status usb_pipe_halt(usb_core_driver *udev, uint8_t pipe_num)
{
__IO uint32_t pp_ctl = udev->regs.pr[pipe_num]->HCHCTL;
uint8_t ep_type = (uint8_t)((pp_ctl & HCHCTL_EPTYPE) >> 18U);
pp_ctl |= HCHCTL_CEN | HCHCTL_CDIS;
switch (ep_type)
{
case USB_EPTYPE_CTRL:
case USB_EPTYPE_BULK:
if (0U == (udev->regs.gr->HNPTFQSTAT & HNPTFQSTAT_NPTXFS))
{
pp_ctl &= ~HCHCTL_CEN;
}
break;
case USB_EPTYPE_INTR:
case USB_EPTYPE_ISOC:
if (0U == (udev->regs.hr->HPTFQSTAT & HPTFQSTAT_PTXFS))
{
pp_ctl &= ~HCHCTL_CEN;
}
break;
default:
break;
}
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl;
return USB_OK;
}
/*!
\brief configure host pipe to do ping operation
\param[in] udev: pointer to USB device
\param[in] pipe_num: host pipe number which is in (0..7)
\param[out] none
\retval operation status
*/
usb_status usb_pipe_ping(usb_core_driver *udev, uint8_t pipe_num)
{
uint32_t pp_ctl = 0U;
udev->regs.pr[pipe_num]->HCHLEN = HCHLEN_PING;
pp_ctl = udev->regs.pr[pipe_num]->HCHCTL;
pp_ctl |= HCHCTL_CEN;
pp_ctl &= ~HCHCTL_CDIS;
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl;
return USB_OK;
}
/*!
\brief stop the USB host and clean up FIFO
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
void usb_host_stop(usb_core_driver *udev)
{
uint32_t i;
__IO uint32_t pp_ctl = 0U;
udev->regs.hr->HACHINTEN = 0x0U;
udev->regs.hr->HACHINT = 0xFFFFFFFFU;
/* flush out any leftover queued requests. */
for (i = 0U; i < udev->bp.num_pipe; i++)
{
pp_ctl = udev->regs.pr[i]->HCHCTL;
pp_ctl &= ~(HCHCTL_CEN | HCHCTL_EPDIR);
pp_ctl |= HCHCTL_CDIS;
udev->regs.pr[i]->HCHCTL = pp_ctl;
}
/* flush the FIFO */
usb_rxfifo_flush(&udev->regs);
usb_txfifo_flush(&udev->regs, 0x10U);
}
#endif /* BSP_USING_USB && RT_USING_USB_HOST */

703
828ECO/drivers/usb/drv_usbd_int.c

@ -0,0 +1,703 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usbd_int.h"
#include "drv_otghs_dev.h"
#include <stdio.h>
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE)
static const uint8_t USB_SPEED[4] = {
[DSTAT_EM_HS_PHY_30MHZ_60MHZ] = (uint8_t)USB_SPEED_HIGH,
[DSTAT_EM_FS_PHY_30MHZ_60MHZ] = (uint8_t)USB_SPEED_FULL,
[DSTAT_EM_FS_PHY_48MHZ] = (uint8_t)USB_SPEED_FULL,
[DSTAT_EM_LS_PHY_6MHZ] = (uint8_t)USB_SPEED_LOW
};
/* local function prototypes ('static') */
static uint32_t usbd_int_epout(usb_core_driver *udev);
static uint32_t usbd_int_epin(usb_core_driver *udev);
static uint32_t usbd_int_rxfifo(usb_core_driver *udev);
static uint32_t usbd_int_reset(usb_core_driver *udev);
static uint32_t usbd_int_enumfinish(usb_core_driver *udev);
static uint32_t usbd_int_suspend(usb_core_driver *udev);
static uint32_t usbd_int_wakeup(usb_core_driver *udev);
#if (1U == LPM_ENABLED)
static uint32_t usbd_int_lpm(usb_core_driver *udev, usb_lpm_type active_type);
#endif /* LPM_ENABLED */
static uint32_t usbd_emptytxfifo_write(usb_core_driver *udev, uint32_t ep_num);
/*!
\brief USB device-mode interrupts global service routine handler
\param[in] udev: pointer to USB device instance
\param[out] none
\retval none
*/
void usbd_isr(usb_core_driver *udev)
{
if (HOST_MODE != (udev->regs.gr->GINTF & GINTF_COPM))
{
uint32_t intr = udev->regs.gr->GINTF;
intr &= udev->regs.gr->GINTEN;
/* there are no interrupts, avoid spurious interrupt */
if (!intr)
{
return;
}
/* OUT endpoints interrupts */
if (intr & GINTF_OEPIF)
{
(void)usbd_int_epout(udev);
}
/* IN endpoints interrupts */
if (intr & GINTF_IEPIF)
{
(void)usbd_int_epin(udev);
}
/* suspend interrupt */
if (intr & GINTF_SP)
{
(void)usbd_int_suspend(udev);
}
/* wakeup interrupt */
if (intr & GINTF_WKUPIF)
{
(void)usbd_int_wakeup(udev);
}
/* start of frame interrupt */
if (intr & GINTF_SOF)
{
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_SOF;
}
/* receive FIFO not empty interrupt */
if (intr & GINTF_RXFNEIF)
{
(void)usbd_int_rxfifo(udev);
}
/* USB reset interrupt */
if (intr & GINTF_RST)
{
(void)usbd_int_reset(udev);
}
/* enumeration has been done interrupt */
if (intr & GINTF_ENUMFIF)
{
(void)usbd_int_enumfinish(udev);
}
/* incomplete synchronization IN transfer interrupt*/
if (intr & GINTF_ISOINCIF)
{
if (NULL != udev->dev.class_core->incomplete_isoc_in)
{
(void)udev->dev.class_core->incomplete_isoc_in(udev);
}
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_ISOINCIF;
}
/* incomplete synchronization OUT transfer interrupt*/
if (intr & GINTF_ISOONCIF)
{
if (NULL != udev->dev.class_core->incomplete_isoc_out)
{
(void)udev->dev.class_core->incomplete_isoc_out(udev);
}
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_ISOONCIF;
}
#if (1U == LPM_ENABLED)
if (intr & GINTF_LPMIF)
{
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_LPMIF;
udev->dev.pm.BESL = (udev->regs.gr->GLPMCFG & GLPMCFG_BESL) >> 2U;
udev->dev.pm.dev_remote_wakeup = (udev->regs.gr->GLPMCFG & GLPMCFG_REW) >> 6U;
if (LPM_L0 == udev->dev.pm.lpm_state)
{
udev->dev.pm.lpm_state = LPM_L1;
usbd_int_lpm(udev, LPM_L1_ACTIVE);
}
else
{
udev->dev.pm.lpm_state = LPM_L0;
usbd_int_lpm(udev, LPM_L0_ACTIVE);
}
}
#endif /* LPM_ENABLED */
#ifdef VBUS_SENSING_ENABLED
/* session request interrupt */
if (intr & GINTF_SESIF)
{
udev->regs.gr->GINTF = GINTF_SESIF;
}
/* OTG mode interrupt */
if (intr & GINTF_OTGIF)
{
if (udev->regs.gr->GOTGINTF & GOTGINTF_SESEND)
{
}
/* clear OTG interrupt */
udev->regs.gr->GINTF = GINTF_OTGIF;
}
#endif /* VBUS_SENSING_ENABLED */
}
}
/*!
\brief indicates that an OUT endpoint has a pending interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
static uint32_t usbd_int_epout(usb_core_driver *udev)
{
uint32_t epintnum = 0U;
uint8_t ep_num = 0U;
for (epintnum = usb_oepintnum_read(udev); epintnum; epintnum >>= 1)
{
if (epintnum & 0x01U)
{
__IO uint32_t oepintr = usb_oepintr_read(udev, ep_num);
/* transfer complete interrupt */
if (oepintr & DOEPINTF_TF)
{
/* clear the bit in DOEPINTF for this interrupt */
udev->regs.er_out[ep_num]->DOEPINTF = DOEPINTF_TF;
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode)
{
__IO uint32_t eplen = udev->regs.er_out[ep_num]->DOEPLEN;
udev->dev.transc_out[ep_num].xfer_count = udev->dev.transc_out[ep_num].max_len -
(eplen & DEPLEN_TLEN);
}
/* inform upper layer: data ready */
usbd_data_out_stage_callback(ep_num, udev->dev.transc_out[ep_num].xfer_len);
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode)
{
if ((0U == ep_num) && ((uint8_t)USB_CTL_STATUS_OUT == udev->dev.control.ctl_state))
{
usb_ctlep_startout(udev);
}
}
}
/* SETUP phase finished interrupt (control endpoints) */
if (oepintr & DOEPINTF_STPF)
{
/* inform the upper layer that a SETUP packet is available */
usbd_setup_stage_callback((struct urequest *)&udev->dev.control.req);
udev->regs.er_out[ep_num]->DOEPINTF = DOEPINTF_STPF;
}
}
ep_num++;
}
return 1U;
}
/*!
\brief indicates that an IN endpoint has a pending interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
static uint32_t usbd_int_epin(usb_core_driver *udev)
{
uint32_t epintnum = 0U;
uint8_t ep_num = 0U;
for (epintnum = usb_iepintnum_read(udev); epintnum; epintnum >>= 1)
{
if (epintnum & 0x1U)
{
__IO uint32_t iepintr = usb_iepintr_read(udev, ep_num);
if (iepintr & DIEPINTF_TF)
{
udev->regs.er_in[ep_num]->DIEPINTF = DIEPINTF_TF;
/* data transmission is completed */
usbd_data_in_stage_callback(ep_num, udev->dev.transc_in[ep_num].xfer_len);
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode)
{
if ((0U == ep_num) && ((uint8_t)USB_CTL_STATUS_IN == udev->dev.control.ctl_state))
{
usb_ctlep_startout(udev);
}
}
}
if (iepintr & DIEPINTF_TXFE)
{
usbd_emptytxfifo_write(udev, (uint32_t)ep_num);
udev->regs.er_in[ep_num]->DIEPINTF = DIEPINTF_TXFE;
}
}
ep_num++;
}
return 1U;
}
/*!
\brief handle the RX status queue level interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
static uint32_t usbd_int_rxfifo(usb_core_driver *udev)
{
usb_transc *transc = NULL;
uint8_t data_PID = 0U;
uint32_t bcount = 0U;
__IO uint32_t devrxstat = 0U;
/* disable the RX status queue non-empty interrupt */
udev->regs.gr->GINTEN &= ~GINTEN_RXFNEIE;
/* get the status from the top of the FIFO */
devrxstat = udev->regs.gr->GRSTATP;
uint8_t ep_num = (uint8_t)(devrxstat & GRSTATRP_EPNUM);
transc = &udev->dev.transc_out[ep_num];
bcount = (devrxstat & GRSTATRP_BCOUNT) >> 4;
data_PID = (uint8_t)((devrxstat & GRSTATRP_DPID) >> 15);
switch ((devrxstat & GRSTATRP_RPCKST) >> 17)
{
case RSTAT_GOUT_NAK:
break;
case RSTAT_DATA_UPDT:
if (bcount > 0U)
{
(void)usb_rxfifo_read(&udev->regs, transc->xfer_buf, (uint16_t)bcount);
transc->xfer_buf += bcount;
transc->xfer_count += bcount;
}
break;
case RSTAT_XFER_COMP:
/* trigger the OUT endpoint interrupt */
break;
case RSTAT_SETUP_COMP:
/* trigger the OUT endpoint interrupt */
break;
case RSTAT_SETUP_UPDT:
if ((0U == transc->ep_addr.num) && (8U == bcount) && (DPID_DATA0 == data_PID))
{
/* copy the SETUP packet received in FIFO into the setup buffer in RAM */
(void)usb_rxfifo_read(&udev->regs, (uint8_t *)&udev->dev.control.req, (uint16_t)bcount);
transc->xfer_count += bcount;
}
break;
default:
break;
}
/* enable the RX status queue level interrupt */
udev->regs.gr->GINTEN |= GINTEN_RXFNEIE;
return 1U;
}
/*!
\brief handle USB reset interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval status
*/
static uint32_t usbd_int_reset(usb_core_driver *udev)
{
uint32_t i;
/* clear the remote wakeup signaling */
udev->regs.dr->DCTL &= ~DCTL_RWKUP;
/* flush the TX FIFO */
(void)usb_txfifo_flush(&udev->regs, 0U);
for (i = 0U; i < udev->bp.num_ep; i++)
{
udev->regs.er_in[i]->DIEPINTF = 0xFFU;
udev->regs.er_out[i]->DOEPINTF = 0xFFU;
}
/* clear all pending device endpoint interrupts */
udev->regs.dr->DAEPINT = 0xFFFFFFFFU;
/* enable endpoint 0 interrupts */
udev->regs.dr->DAEPINTEN = 1U | (1U << 16U);
/* enable OUT endpoint interrupts */
udev->regs.dr->DOEPINTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN;
#ifdef USB_DEDICATED_EP1_ENABLED
udev->regs.dr->DOEP1INTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN;
#endif
/* enable IN endpoint interrupts */
udev->regs.dr->DIEPINTEN = DIEPINTEN_TFEN;
#ifdef USB_DEDICATED_EP1_ENABLED
udev->regs.dr->DIEP1INTEN = DIEPINTEN_TFEN;
#endif
/* reset device address */
udev->regs.dr->DCFG &= ~DCFG_DAR;
/* configure endpoint 0 to receive SETUP packets */
usb_ctlep_startout(udev);
/* clear USB reset interrupt */
udev->regs.gr->GINTF = GINTF_RST;
usb_ep_active(udev, 0x00, USB_FS_EP0_MAX_LEN, USB_EPTYPE_CTRL);
usb_ep_active(udev, 0x80, USB_FS_EP0_MAX_LEN, USB_EPTYPE_CTRL);
usbd_reset_callback();
return 1U;
}
/*!
\brief handle USB speed enumeration finish interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval status
*/
static uint32_t usbd_int_enumfinish(usb_core_driver *udev)
{
uint8_t enum_speed = (uint8_t)((udev->regs.dr->DSTAT & DSTAT_ES) >> 1);
udev->regs.dr->DCTL &= ~DCTL_CGINAK;
udev->regs.dr->DCTL |= DCTL_CGINAK;
udev->regs.gr->GUSBCS &= ~GUSBCS_UTT;
/* set USB turn-around time based on device speed and PHY interface */
if ((uint8_t)USB_SPEED_HIGH == USB_SPEED[enum_speed])
{
udev->bp.core_speed = (uint8_t)USB_SPEED_HIGH;
udev->regs.gr->GUSBCS |= 0x09U << 10;
}
else
{
udev->bp.core_speed = (uint8_t)USB_SPEED_FULL;
udev->regs.gr->GUSBCS |= 0x05U << 10;
}
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_ENUMFIF;
return 1U;
}
/*!
\brief USB suspend interrupt handler
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
static uint32_t usbd_int_suspend(usb_core_driver *udev)
{
__IO uint8_t low_power = udev->bp.low_power;
__IO uint8_t suspend = (uint8_t)(udev->regs.dr->DSTAT & DSTAT_SPST);
udev->dev.backup_status = udev->dev.cur_status;
if (low_power && suspend)
{
/* switch-off the USB clocks */
*udev->regs.PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK;
/* enter DEEP_SLEEP mode with LDO in low power mode */
pmu_to_deepsleepmode(WFI_CMD);
}
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_SP;
return 1U;
}
/*!
\brief USB wakeup interrupt handler
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
static uint32_t usbd_int_wakeup(usb_core_driver *udev)
{
__IO uint8_t low_power = udev->bp.low_power;
__IO uint8_t remote_wakeup = udev->dev.pm.dev_remote_wakeup;
#if (1U == LPM_ENABLED)
if (LPM_L1 == udev->dev.pm.lpm_state)
{
udev->dev.pm.lpm_state = LPM_L0;
usbd_int_lpm(udev, LPM_L0_ACTIVE);
}
else
#endif /* LPM_ENABLED */
{
if (remote_wakeup && low_power)
{
/* resume MCU CLK */
/* reset SLEEPDEEP bit of Cortex-M33 system control register */
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
}
usb_clock_active(udev);
/* inform upper layer by the resume event */
udev->dev.cur_status = udev->dev.backup_status;
}
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_WKUPIF;
return 1U;
}
#ifdef USB_DEDICATED_EP1_ENABLED
/*!
\brief USB dedicated OUT endpoint 1 interrupt service routine handler
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
uint32_t usbd_int_dedicated_ep1out(usb_core_driver *udev)
{
uint32_t oepintr = 0U;
uint32_t oeplen = 0U;
oepintr = udev->regs.er_out[1]->DOEPINTF;
oepintr &= udev->regs.dr->DOEP1INTEN;
/* transfer complete */
if (oepintr & DOEPINTF_TF)
{
/* clear the bit in DOEPINTn for this interrupt */
udev->regs.er_out[1]->DOEPINTF = DOEPINTF_TF;
if (USB_USE_DMA == udev->bp.transfer_mode)
{
oeplen = udev->regs.er_out[1]->DOEPLEN;
/* ToDo : handle more than one single MPS size packet */
udev->dev.transc_out[1].xfer_count = udev->dev.transc_out[1].max_len -
(oeplen & DEPLEN_TLEN);
}
/* RX COMPLETE */
usbd_out_transc(udev, 1U);
}
return 1U;
}
/*!
\brief USB dedicated IN endpoint 1 interrupt service routine handler
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
uint32_t usbd_int_dedicated_ep1in(usb_core_driver *udev)
{
uint32_t inten, intr, emptyen;
inten = udev->regs.dr->DIEP1INTEN;
emptyen = udev->regs.dr->DIEPFEINTEN;
inten |= ((emptyen >> 1U) & 0x1U) << 7U;
intr = udev->regs.er_in[1]->DIEPINTF & inten;
if (intr & DIEPINTF_TF)
{
udev->regs.dr->DIEPFEINTEN &= ~(0x1U << 1U);
udev->regs.er_in[1]->DIEPINTF = DIEPINTF_TF;
/* TX COMPLETE */
usbd_in_transc(udev, 1U);
}
if (intr & DIEPINTF_TXFE)
{
usbd_emptytxfifo_write(udev, 1U);
udev->regs.er_in[1]->DIEPINTF = DIEPINTF_TXFE;
}
return 1U;
}
#endif
#if (1U == LPM_ENABLED)
/*!
\brief USB LPM interrupt handler
\param[in] udev: pointer to USB device instance
\param[in] active_type: active type
only one parameter can be selected which is shown as below:
\arg LPM_L0_ACTIVE: select L0 to active
\arg LPM_L1_ACTIVE: select L1 to active
\param[out] none
\retval operation status
*/
static uint32_t usbd_int_lpm(usb_core_driver *udev, usb_lpm_type active_type)
{
__IO uint8_t low_power = udev->bp.low_power;
__IO uint8_t suspend = (uint8_t)(udev->regs.dr->DSTAT & DSTAT_SPST);
__IO uint8_t is_configured = (udev->dev.cur_status == (uint8_t)USBD_CONFIGURED) ? 1U : 0U;
switch (active_type)
{
case LPM_L0_ACTIVE:
udev->dev.cur_status = udev->dev.backup_status;
/* switch-on the OTG clocks */
usb_clock_active(udev);
if (low_power)
{
/* resume MCU CLK */
/* reset SLEEPDEEP bit of Cortex-M7 system control register */
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
}
break;
case LPM_L1_ACTIVE:
udev->dev.backup_status = udev->dev.cur_status;
udev->dev.cur_status = (uint8_t)USBD_SUSPENDED;
/* add delay */
usb_mdelay(300U);
/* switch-off the OTG clocks */
*udev->regs.PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK;
if (low_power)
{
/* enter DEEP_SLEEP mode with LDO in low power mode */
pmu_to_deepsleepmode(WFI_CMD);
}
break;
}
return 1U;
}
#endif /* LPM_ENABLED */
/*!
\brief check FIFO for the next packet to be loaded
\param[in] udev: pointer to USB device instance
\param[in] ep_num: endpoint identifier which is in (0..5)
\param[out] none
\retval status
*/
static uint32_t usbd_emptytxfifo_write(usb_core_driver *udev, uint32_t ep_num)
{
uint32_t len;
uint32_t word_count;
usb_transc *transc = &udev->dev.transc_in[ep_num];
len = transc->xfer_len - transc->xfer_count;
/* get the data length to write */
if (len > transc->max_len)
{
len = transc->max_len;
}
word_count = (len + 3U) / 4U;
while (((udev->regs.er_in[ep_num]->DIEPTFSTAT & DIEPTFSTAT_IEPTFS) >= word_count) &&
(transc->xfer_count < transc->xfer_len))
{
len = transc->xfer_len - transc->xfer_count;
if (len > transc->max_len)
{
len = transc->max_len;
}
/* write FIFO in word(4bytes) */
word_count = (len + 3U) / 4U;
/* write the FIFO */
(void)usb_txfifo_write(&udev->regs, transc->xfer_buf, (uint8_t)ep_num, (uint16_t)len);
transc->xfer_buf += len;
transc->xfer_count += len;
if (transc->xfer_count == transc->xfer_len)
{
/* disable the device endpoint FIFO empty interrupt */
udev->regs.dr->DIEPFEINTEN &= ~(0x01U << ep_num);
}
}
return 1U;
}
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */

693
828ECO/drivers/usb/drv_usbh_int.c

@ -0,0 +1,693 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usbh_int.h"
#include "drv_otghs_host.h"
#if defined(__CC_ARM) /*!< ARM compiler */
#pragma O0
#elif defined(__GNUC__) /*!< GNU compiler */
#pragma GCC optimize("O0")
#elif defined(__TASKING__) /*!< TASKING compiler */
#pragma optimize = 0
#endif /* __CC_ARM */
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
/* local function prototypes ('static') */
static uint32_t usbh_int_port(usb_core_driver *udev);
static uint32_t usbh_int_pipe(usb_core_driver *udev);
static uint32_t usbh_int_pipe_in(usb_core_driver *udev, uint32_t pp_num);
static uint32_t usbh_int_pipe_out(usb_core_driver *udev, uint32_t pp_num);
static uint32_t usbh_int_rxfifonoempty(usb_core_driver *udev);
static uint32_t usbh_int_txfifoempty(usb_core_driver *udev, usb_pipe_mode pp_mode);
/*!
\brief handle global host interrupt
\param[in] udev: pointer to USB core instance
\param[out] none
\retval operation status
*/
uint32_t usbh_isr(usb_core_driver *udev)
{
uint32_t retval = 0U;
__IO uint32_t intr = 0U;
/* check if host mode */
if (HOST_MODE == (udev->regs.gr->GINTF & GINTF_COPM))
{
intr = usb_coreintr_get(&udev->regs);
if (!intr)
{
return 0U;
}
if (intr & GINTF_SOF)
{
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_SOF;
}
if (intr & GINTF_RXFNEIF)
{
retval |= usbh_int_rxfifonoempty(udev);
}
if (intr & GINTF_NPTXFEIF)
{
retval |= usbh_int_txfifoempty(udev, PIPE_NON_PERIOD);
}
if (intr & GINTF_PTXFEIF)
{
retval |= usbh_int_txfifoempty(udev, PIPE_PERIOD);
}
if (intr & GINTF_HCIF)
{
retval |= usbh_int_pipe(udev);
}
if (intr & GINTF_HPIF)
{
retval |= usbh_int_port(udev);
}
if (intr & GINTF_WKUPIF)
{
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_WKUPIF;
}
if (intr & GINTF_DISCIF)
{
if ((*udev->regs.HPCS & HPCS_PCST) == 0)
{
usbh_disconnect_callback(udev);
}
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_DISCIF;
}
if (intr & GINTF_ISOONCIF)
{
udev->regs.pr[0]->HCHCTL |= HCHCTL_CEN | HCHCTL_CDIS;
/* clear interrupt */
udev->regs.gr->GINTF = GINTF_ISOONCIF;
}
}
return retval;
}
/*!
\brief handle USB pipe halt
\param[in] udev: pointer to USB core instance
\param[in] pp_num: pp_num: host channel number which is in (0..7)
\param[in] pp_int: pipe interrupt
\param[in] pp_status: pipe status
\param[out] none
\retval none
*/
static inline void usb_pp_halt(usb_core_driver *udev,
uint8_t pp_num,
uint32_t pp_int,
usb_pipe_status pp_status)
{
udev->regs.pr[pp_num]->HCHINTEN |= HCHINTEN_CHIE;
usb_pipe_halt(udev, pp_num);
udev->regs.pr[pp_num]->HCHINTF = pp_int;
udev->host.pipe[pp_num].pp_status = pp_status;
}
/*!
\brief handle the host port interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
#if defined(__ICCARM__) /*!< IAR compiler */
#pragma optimize = none
#endif /* __ICCARM */
static uint32_t usbh_int_port(usb_core_driver *udev)
{
uint32_t retval = 0U;
__IO uint32_t port_state = *udev->regs.HPCS;
__IO uint32_t port_reset = 0U;
/* clear the interrupt bit in GINTF */
port_state &= ~(HPCS_PE | HPCS_PCD | HPCS_PEDC);
/* port connect detected */
if (*udev->regs.HPCS & HPCS_PCD)
{
port_state |= HPCS_PCD;
if ((*udev->regs.HPCS & HPCS_PCST) == HPCS_PCST)
{
usbh_connect_callback(udev);
}
retval |= 1U;
}
/* port enable changed */
if (*udev->regs.HPCS & HPCS_PEDC)
{
port_state |= HPCS_PEDC;
if (*udev->regs.HPCS & HPCS_PE)
{
uint32_t port_speed = usb_curspeed_get(udev);
udev->host.connect_status = 1U;
if (PORT_SPEED_LOW == port_speed)
{
udev->regs.hr->HFT = 6000U;
}
else if (PORT_SPEED_FULL == port_speed)
{
udev->regs.hr->HFT = 48000U;
}
else
{
/* no operation */
}
port_reset = 1U;
udev->regs.gr->GINTEN |= GINTEN_DISCIE | GINTEN_SOFIE;
}
else
{
/* no operation */
}
}
if (1U == port_reset)
{
usb_port_reset(udev);
}
/* clear port interrupts */
*udev->regs.HPCS = port_state;
return retval;
}
/*!
\brief handle all host channels interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
static uint32_t usbh_int_pipe(usb_core_driver *udev)
{
uint32_t pp_num = 0U;
uint32_t retval = 0U;
for (pp_num = 0U; pp_num < udev->bp.num_pipe; pp_num++)
{
if ((udev->regs.hr->HACHINT & HACHINT_HACHINT) & (1UL << pp_num))
{
if (udev->regs.pr[pp_num]->HCHCTL & HCHCTL_EPDIR)
{
retval |= usbh_int_pipe_in(udev, pp_num);
}
else
{
retval |= usbh_int_pipe_out(udev, pp_num);
}
}
}
return retval;
}
/*!
\brief handle the IN channel interrupt
\param[in] udev: pointer to USB device instance
\param[in] pp_num: host channel number which is in (0..7)
\param[out] none
\retval operation status
*/
#if defined(__ICCARM__) /*!< IAR compiler */
#pragma optimize = none
#endif /* __ICCARM */
static uint32_t usbh_int_pipe_in(usb_core_driver *udev, uint32_t pp_num)
{
usb_pr *pp_reg = udev->regs.pr[pp_num];
usb_pipe *pp = &udev->host.pipe[pp_num];
uint32_t intr_pp = pp_reg->HCHINTF;
intr_pp &= pp_reg->HCHINTEN;
uint8_t ep_type = (uint8_t)((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18);
if (intr_pp & HCHINTF_ACK)
{
pp_reg->HCHINTF = HCHINTF_ACK;
}
else if (intr_pp & HCHINTF_STALL)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_STALL, PIPE_STALL);
pp_reg->HCHINTF = HCHINTF_NAK;
/* note: When there is a 'STALL', reset also NAK,
else, the udev->host.pp_status = HC_STALL
will be overwritten by 'NAK' in code below */
intr_pp &= ~HCHINTF_NAK;
}
else if (intr_pp & HCHINTF_DTER)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_DTER, PIPE_DTGERR);
pp_reg->HCHINTF = HCHINTF_NAK;
}
else
{
/* no operation */
}
if (intr_pp & HCHINTF_REQOVR)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_REQOVR, PIPE_REQOVR);
}
else if (intr_pp & HCHINTF_TF)
{
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode)
{
udev->host.backup_xfercount[pp_num] = pp->xfer_len - (pp_reg->HCHLEN & HCHLEN_TLEN);
}
pp->pp_status = PIPE_XF;
pp->err_count = 0U;
pp_reg->HCHINTF = HCHINTF_TF;
switch (ep_type)
{
case USB_EPTYPE_CTRL:
case USB_EPTYPE_BULK:
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_XF);
pp->data_toggle_in ^= 1U;
break;
case USB_EPTYPE_INTR:
case USB_EPTYPE_ISOC:
pp_reg->HCHCTL |= HCHCTL_ODDFRM;
pp->urb_state = URB_DONE;
#ifdef USBH_USE_RTOS
usbh_hc_notifyurbchange_callback(udev, pp_num, pp->urb_state);
#endif /* USBH_USE_RTOS */
break;
default:
break;
}
}
else if (intr_pp & HCHINTF_CH)
{
pp_reg->HCHINTEN &= ~HCHINTEN_CHIE;
switch (pp->pp_status)
{
case PIPE_XF:
pp->urb_state = URB_DONE;
break;
case PIPE_STALL:
pp->urb_state = URB_STALL;
break;
case PIPE_TRACERR:
case PIPE_DTGERR:
pp->err_count = 0U;
pp->urb_state = URB_ERROR;
pp->data_toggle_in ^= 1U;
break;
case PIPE_IDLE:
case PIPE_HALTED:
case PIPE_NAK:
case PIPE_NYET:
case PIPE_BBERR:
case PIPE_REQOVR:
default:
if ((uint8_t)USB_EPTYPE_INTR == ep_type)
{
pp->data_toggle_in ^= 1U;
}
break;
}
#ifdef USBH_USE_RTOS
usbh_hc_notifyurbchange_callback(udev, pp_num, pp->urb_state);
#endif /* USBH_USE_RTOS */
pp_reg->HCHINTF = HCHINTF_CH;
}
else if (intr_pp & HCHINTF_USBER)
{
pp->err_count++;
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_USBER, PIPE_TRACERR);
}
else if (intr_pp & HCHINTF_NAK)
{
pp_reg->HCHINTF = HCHINTF_NAK;
switch (ep_type)
{
case USB_EPTYPE_CTRL:
case USB_EPTYPE_BULK:
/* re-activate the channel */
pp_reg->HCHCTL = (pp_reg->HCHCTL | HCHCTL_CEN) & ~HCHCTL_CDIS;
break;
case USB_EPTYPE_INTR:
pp_reg->HCHINTEN |= HCHINTEN_CHIE;
(void)usb_pipe_halt(udev, (uint8_t)pp_num);
break;
default:
break;
}
pp->pp_status = PIPE_NAK;
}
else
{
/* no operation */
}
return 1U;
}
/*!
\brief handle the OUT channel interrupt
\param[in] udev: pointer to USB device instance
\param[in] pp_num: host channel number which is in (0..7)
\param[out] none
\retval operation status
*/
#if defined(__ICCARM__) /*!< IAR compiler */
#pragma optimize = none
#endif /* __ICCARM */
static uint32_t usbh_int_pipe_out(usb_core_driver *udev, uint32_t pp_num)
{
usb_pr *pp_reg = udev->regs.pr[pp_num];
usb_pipe *pp = &udev->host.pipe[pp_num];
uint32_t intr_pp = pp_reg->HCHINTF;
intr_pp &= pp_reg->HCHINTEN;
if (intr_pp & HCHINTF_ACK)
{
if (1U == udev->host.pipe[pp_num].do_ping)
{
udev->host.pipe[pp_num].do_ping = 0U;
pp->err_count = 0U;
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_ACK, PIPE_NAK);
}
pp_reg->HCHINTF = HCHINTF_ACK;
}
else if (intr_pp & HCHINTF_STALL)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_STALL, PIPE_STALL);
}
else if (intr_pp & HCHINTF_DTER)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_DTER, PIPE_DTGERR);
pp_reg->HCHINTF = HCHINTF_NAK;
}
else if (intr_pp & HCHINTF_REQOVR)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_REQOVR, PIPE_REQOVR);
}
else if (intr_pp & HCHINTF_TF)
{
pp->err_count = 0U;
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_TF, PIPE_XF);
}
else if (intr_pp & HCHINTF_NAK)
{
if (0U == udev->host.pipe[pp_num].do_ping)
{
if (1U == udev->host.pipe[pp_num].supp_ping)
{
udev->host.pipe[pp_num].do_ping = 1U;
}
}
pp->err_count = 0U;
if (USB_USE_FIFO == udev->bp.transfer_mode)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_NAK);
}
else
{
pp_reg->HCHINTF = HCHINTF_NAK;
}
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_NAK);
}
else if (intr_pp & HCHINTF_USBER)
{
pp->err_count++;
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_USBER, PIPE_TRACERR);
}
else if (intr_pp & HCHINTF_NYET)
{
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NYET, PIPE_NYET);
pp->err_count = 0U;
}
else if (intr_pp & HCHINTF_CH)
{
udev->regs.pr[pp_num]->HCHINTEN &= ~HCHINTEN_CHIE;
switch (pp->pp_status)
{
case PIPE_XF:
pp->urb_state = URB_DONE;
if ((uint8_t)USB_EPTYPE_BULK == ((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18U))
{
pp->data_toggle_out ^= 1U;
}
break;
case PIPE_NAK:
pp->urb_state = URB_NOTREADY;
break;
case PIPE_NYET:
pp->urb_state = URB_DONE;
if ((uint8_t)USB_EPTYPE_BULK == ((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18U))
{
pp->data_toggle_out ^= 1U;
}
break;
case PIPE_STALL:
pp->urb_state = URB_STALL;
break;
case PIPE_TRACERR:
if (3U == pp->err_count)
{
pp->urb_state = URB_ERROR;
pp->err_count = 0U;
}
break;
case PIPE_IDLE:
case PIPE_HALTED:
case PIPE_BBERR:
case PIPE_REQOVR:
case PIPE_DTGERR:
default:
break;
}
#ifdef USBH_USE_RTOS
usbh_hc_notifyurbchange_callback(udev, pp_num, pp->urb_state);
#endif /* USBH_USE_RTOS */
pp_reg->HCHINTF = HCHINTF_CH;
}
else
{
/* no operation */
}
return 1U;
}
/*!
\brief handle the RX FIFO non-empty interrupt
\param[in] udev: pointer to USB device instance
\param[out] none
\retval operation status
*/
#if defined(__ICCARM__) /*!< IAR compiler */
#pragma optimize = none
#endif /* __ICCARM */
static uint32_t usbh_int_rxfifonoempty(usb_core_driver *udev)
{
uint32_t count = 0U, xfer_count = 0U;
__IO uint8_t pp_num = 0U;
__IO uint32_t rx_stat = 0U;
/* disable the RX status queue level interrupt */
udev->regs.gr->GINTEN &= ~GINTEN_RXFNEIE;
rx_stat = udev->regs.gr->GRSTATP;
pp_num = (uint8_t)(rx_stat & GRSTATRP_CNUM);
switch ((rx_stat & GRSTATRP_RPCKST) >> 17)
{
case GRXSTS_PKTSTS_IN:
count = (rx_stat & GRSTATRP_BCOUNT) >> 4;
/* read the data into the host buffer. */
if ((NULL != udev->host.pipe[pp_num].xfer_buf) && (count > 0U))
{
(void)usb_rxfifo_read(&udev->regs, udev->host.pipe[pp_num].xfer_buf, (uint16_t)count);
/* manage multiple transfer packet */
udev->host.pipe[pp_num].xfer_buf += count;
udev->host.pipe[pp_num].xfer_count += count;
xfer_count = udev->host.pipe[pp_num].xfer_count;
udev->host.backup_xfercount[pp_num] = xfer_count;
if (udev->regs.pr[pp_num]->HCHLEN & HCHLEN_PCNT)
{
/* re-activate the channel when more packets are expected */
uint32_t pp_ctl = udev->regs.pr[pp_num]->HCHCTL;
pp_ctl |= HCHCTL_CEN;
pp_ctl &= ~HCHCTL_CDIS;
udev->regs.pr[pp_num]->HCHCTL = pp_ctl;
}
}
break;
case GRXSTS_PKTSTS_IN_XFER_COMP:
break;
case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
count = (rx_stat & GRSTATRP_BCOUNT) >> 4;
while (count > 0U)
{
rx_stat = udev->regs.gr->GRSTATP;
count--;
}
break;
case GRXSTS_PKTSTS_CH_HALTED:
break;
default:
break;
}
/* enable the RX status queue level interrupt */
udev->regs.gr->GINTEN |= GINTEN_RXFNEIE;
return 1U;
}
/*!
\brief handle the TX FIFO empty interrupt
\param[in] udev: pointer to USB device instance
\param[in] pp_mode: pipe mode
\param[out] none
\retval operation status
*/
#if defined(__ICCARM__) /*!< IAR compiler */
#pragma optimize = none
#endif /* __ICCARM */
static uint32_t usbh_int_txfifoempty(usb_core_driver *udev, usb_pipe_mode pp_mode)
{
uint8_t pp_num = 0U;
uint16_t word_count = 0U, len = 0U;
__IO uint32_t *txfiforeg = 0U, txfifostate = 0U;
if (PIPE_NON_PERIOD == pp_mode)
{
txfiforeg = &udev->regs.gr->HNPTFQSTAT;
}
else if (PIPE_PERIOD == pp_mode)
{
txfiforeg = &udev->regs.hr->HPTFQSTAT;
}
else
{
return 0U;
}
txfifostate = *txfiforeg;
pp_num = (uint8_t)((txfifostate & TFQSTAT_CNUM) >> 27);
word_count = (uint16_t)(udev->host.pipe[pp_num].xfer_len + 3U) / 4U;
while (((txfifostate & TFQSTAT_TXFS) >= word_count) && (0U != udev->host.pipe[pp_num].xfer_len))
{
len = (uint16_t)(txfifostate & TFQSTAT_TXFS) * 4U;
if (len > udev->host.pipe[pp_num].xfer_len)
{
/* last packet */
len = (uint16_t)udev->host.pipe[pp_num].xfer_len;
if (PIPE_NON_PERIOD == pp_mode)
{
udev->regs.gr->GINTEN &= ~GINTEN_NPTXFEIE;
}
else
{
udev->regs.gr->GINTEN &= ~GINTEN_PTXFEIE;
}
}
word_count = (uint16_t)((udev->host.pipe[pp_num].xfer_len + 3U) / 4U);
usb_txfifo_write(&udev->regs, udev->host.pipe[pp_num].xfer_buf, pp_num, len);
udev->host.pipe[pp_num].xfer_buf += len;
udev->host.pipe[pp_num].xfer_len -= len;
udev->host.pipe[pp_num].xfer_count += len;
txfifostate = *txfiforeg;
}
return 1U;
}
#endif /* BSP_USING_USB && RT_USING_USB_HOST */

178
828ECO/drivers/usb/drv_usbh_pipe.c

@ -0,0 +1,178 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usbh_pipe.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
static uint16_t usbh_freepipe_get(usb_core_driver *pudev);
/*!
\brief create a pipe
\param[in] pudev: pointer to usb core instance
\param[in] pp_num: pipe number
\param[in] udev: USB device
\param[in] ep_type: endpoint type
\param[in] ep_mpl: endpoint max packet length
\param[out] none
\retval operation status
*/
uint8_t usbh_pipe_create(usb_core_driver *pudev,
uint8_t dev_addr,
uint8_t dev_speed,
uint8_t pp_num,
uint8_t ep_num,
uint8_t ep_type,
uint16_t ep_mpl)
{
usb_pipe *pp = &pudev->host.pipe[pp_num];
pp->dev_addr = dev_addr;
pp->dev_speed = dev_speed;
pp->ep.num = ep_num & 0x7FU;
pp->ep.type = ep_type;
pp->ep.mps = ep_mpl;
if (((USB_EPTYPE_BULK == pp->ep.type) || (USB_EPTYPE_CTRL == pp->ep.type)))
{
pp->supp_ping = (uint8_t)(pp->dev_speed == PORT_SPEED_HIGH);
}
if (0x80U == (ep_num & 0x80U))
{
pp->ep.dir = 1;
}
else
{
pp->ep.dir = 0;
}
usb_pipe_init(pudev, pp_num);
return HC_OK;
}
/*!
\brief modify a pipe
\param[in] pudev: pointer to usb core instance
\param[in] pp_num: pipe number
\param[in] dev_addr: device address
\param[in] dev_speed: device speed
\param[in] ep_type: endpoint type
\param[in] ep_mpl: endpoint max packet length
\param[out] none
\retval operation status
*/
uint8_t usbh_pipe_update(usb_core_driver *pudev,
uint8_t pp_num,
uint8_t dev_addr,
uint32_t dev_speed,
uint16_t ep_mpl)
{
usb_pipe *pp = &pudev->host.pipe[pp_num];
if ((pp->dev_addr != dev_addr) && (dev_addr))
{
pp->dev_addr = dev_addr;
}
if ((pp->dev_speed != dev_speed) && (dev_speed))
{
pp->dev_speed = dev_speed;
}
if ((pp->ep.mps != ep_mpl) && (ep_mpl))
{
pp->ep.mps = ep_mpl;
}
usb_pipe_init(pudev, pp_num);
return HC_OK;
}
/*!
\brief allocate a new pipe
\param[in] pudev: pointer to usb core instance
\param[in] ep_addr: endpoint address
\param[out] none
\retval operation status
*/
uint8_t usbh_pipe_allocate(usb_core_driver *pudev, uint8_t ep_addr)
{
uint16_t pp_num = usbh_freepipe_get(pudev);
if (HC_ERROR != pp_num)
{
pudev->host.pipe[pp_num].in_used = 1U;
pudev->host.pipe[pp_num].ep.dir = EP_DIR(ep_addr);
pudev->host.pipe[pp_num].ep.num = EP_ID(ep_addr);
}
return pp_num;
}
/*!
\brief free a pipe
\param[in] pudev: pointer to usb core instance
\param[in] pp_num: pipe number
\param[out] none
\retval operation status
*/
uint8_t usbh_pipe_free(usb_core_driver *pudev, uint8_t pp_num)
{
if (pp_num < HC_MAX)
{
pudev->host.pipe[pp_num].in_used = 0U;
}
return USBH_OK;
}
/*!
\brief delete all USB host pipe
\param[in] pudev: pointer to usb core instance
\param[out] none
\retval operation status
*/
uint8_t usbh_pipe_delete(usb_core_driver *pudev)
{
uint8_t pp_num = 0U;
for (pp_num = 2U; pp_num < HC_MAX; pp_num++)
{
pudev->host.pipe[pp_num] = (usb_pipe){ 0 };
}
return USBH_OK;
}
/*!
\brief get a free pipe number for allocation
\param[in] pudev: pointer to usb core instance
\param[out] none
\retval operation status
*/
static uint16_t usbh_freepipe_get(usb_core_driver *pudev)
{
uint8_t pp_num = 0U;
for (pp_num = 0U; pp_num < HC_MAX; pp_num++)
{
if (pudev->host.pipe[pp_num].in_used == 0U)
{
return pp_num;
}
}
return HC_ERROR;
}
#endif /* BSP_USING_USB && RT_USING_USB_HOST */

147
828ECO/drivers/usb/drv_usbh_trans.c

@ -0,0 +1,147 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usbh_transc.h"
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST)
#define USB_SETUP_PACKET_LEN 8U
/*!
\brief prepare a pipe and start a transfer
\param[in] pudev: pointer to usb core instance
\param[in] pp_num: pipe number
\param[out] none
\retval operation status
*/
static uint32_t usbh_request_submit(usb_core_driver *pudev, uint8_t pp_num)
{
pudev->host.pipe[pp_num].urb_state = URB_IDLE;
pudev->host.pipe[pp_num].xfer_count = 0U;
return usb_pipe_xfer(pudev, pp_num);
}
/*!
\brief send the setup packet to the USB device
\param[in] pudev: pointer to usb core instance
\param[in] buf: data buffer which will be sent to USB device
\param[in] pp_num: pipe number
\param[out] none
\retval operation status
*/
usbh_status usbh_ctlsetup_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num)
{
usb_pipe *pp = &pudev->host.pipe[pp_num];
pp->DPID = PIPE_DPID_SETUP;
pp->xfer_buf = buf;
pp->xfer_len = USB_SETUP_PACKET_LEN;
return (usbh_status)usbh_request_submit(pudev, pp_num);
}
/*!
\brief send a data packet to the USB device
\param[in] pudev: pointer to usb core instance
\param[in] buf: data buffer which will be sent to USB device
\param[in] pp_num: pipe number
\param[in] len: length of the data to be sent
\param[out] none
\retval operation status
*/
usbh_status usbh_data_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len)
{
usb_pipe *pp = &pudev->host.pipe[pp_num];
pp->xfer_buf = buf;
pp->xfer_len = len;
switch (pp->ep.type)
{
case USB_EPTYPE_CTRL:
if (0U == len)
{
pp->data_toggle_out = 1U;
}
pp->DPID = PIPE_DPID[pp->data_toggle_out];
break;
case USB_EPTYPE_INTR:
pp->DPID = PIPE_DPID[pp->data_toggle_out];
pp->data_toggle_out ^= 1U;
break;
case USB_EPTYPE_BULK:
pp->DPID = PIPE_DPID[pp->data_toggle_out];
break;
case USB_EPTYPE_ISOC:
pp->DPID = PIPE_DPID[0];
break;
default:
break;
}
usbh_request_submit(pudev, pp_num);
return USBH_OK;
}
/*!
\brief receive a data packet from the USB device
\param[in] pudev: pointer to usb core instance
\param[in] buf: data buffer which will be received from USB device
\param[in] pp_num: pipe number
\param[in] len: length of the data to be received
\param[out] none
\retval operation status
*/
usbh_status usbh_data_recev(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len)
{
usb_pipe *pp = &pudev->host.pipe[pp_num];
pp->xfer_buf = buf;
pp->xfer_len = len;
switch (pp->ep.type)
{
case USB_EPTYPE_CTRL:
pp->DPID = PIPE_DPID[1];
break;
case USB_EPTYPE_INTR:
pp->DPID = PIPE_DPID[pp->data_toggle_in];
/* Toggle DATA PID */
pp->data_toggle_in ^= 1U;
break;
case USB_EPTYPE_BULK:
pp->DPID = PIPE_DPID[pp->data_toggle_in];
break;
case USB_EPTYPE_ISOC:
pp->DPID = PIPE_DPID[0];
break;
default:
break;
}
usbh_request_submit(pudev, pp_num);
return USBH_OK;
}
#endif /* BSP_USING_USB && RT_USING_USB_HOST */

733
828ECO/drivers/usb/gd32h7_usb_hw.c

@ -0,0 +1,733 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-07 RealThread the first version
*/
#include "drv_usb_hw.h"
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#if defined(BSP_USING_USB)
#define TIM_MSEC_DELAY 0x01U
#define TIM_USEC_DELAY 0x02U
#if defined(RT_USING_USB_HOST)
#ifndef USE_ULPI_PHY
#ifdef USE_USBHS0
#if defined(SOC_SERIES_GD32H75E)
#define HOST_POWERSW_PORT_RCC RCU_GPIOG
#define HOST_POWERSW_PORT GPIOG
#define HOST_POWERSW_VBUS GPIO_PIN_8
#elif defined(SOC_SERIES_GD32H7xx)
#warning "Please refer to the relevant sections in the chip manual to redefine the pins."
#define HOST_POWERSW_PORT_RCC RCU_GPIOB
#define HOST_POWERSW_PORT GPIOB
#define HOST_POWERSW_VBUS GPIO_PIN_13
#endif
#endif
#ifdef USE_USBHS1
#define HOST_POWERSW_PORT_RCC RCU_GPIOG
#define HOST_POWERSW_PORT GPIOG
#define HOST_POWERSW_VBUS GPIO_PIN_7
#endif
#else
#ifdef USE_USBHS0
#define HOST_POWERSW_PORT_RCC RCU_GPIOC
#define HOST_POWERSW_PORT GPIOC
#define HOST_POWERSW_VBUS GPIO_PIN_7
#endif
#ifdef USE_USBHS1
#define HOST_POWERSW_PORT_RCC RCU_GPIOC
#define HOST_POWERSW_PORT GPIOC
#define HOST_POWERSW_VBUS GPIO_PIN_9
#endif
#endif
#define HOST_SOF_OUTPUT_RCC RCC_APB2PERIPH_GPIOA
#define HOST_SOF_PORT GPIOA
#define HOST_SOF_SIGNAL GPIO_PIN_8
#endif
__IO uint32_t delay_time = 0U;
__IO uint16_t timer_prescaler = 23U;
/* local function prototypes ('static') */
static void hw_time_set(uint8_t unit);
static void hw_delay(uint32_t ntime, uint8_t unit);
/*!
\brief configure USB GPIO
\param[in] none
\param[out] none
\retval none
*/
void usb_gpio_config(void)
{
#ifdef USE_USBHS0
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
/* ULPI_STP(PC0) GPIO pin configuration */
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_0);
/* ULPI_CK(PA5) GPIO pin configuration */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_5);
/* ULPI_NXT(PC3) GPIO pin configuration */
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_3);
/* ULPI_DIR(PC2) GPIO pin configuration */
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_2);
/* ULPI_D1(PB0), ULPI_D2(PB1), ULPI_D3(PB10), ULPI_D4(PB11) \
ULPI_D5(PB12), ULPI_D6(PB13) and ULPI_D7(PB5) GPIO pin configuration */
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE,
GPIO_PIN_0 |
GPIO_PIN_1 | GPIO_PIN_10 | GPIO_PIN_11);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ,
GPIO_PIN_12 |
GPIO_PIN_13 | GPIO_PIN_5);
/* ULPI_D0(PA3) GPIO pin configuration */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_3);
gpio_af_set(GPIOA, GPIO_AF_10, GPIO_PIN_5);
gpio_af_set(GPIOB, GPIO_AF_10, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13);
gpio_af_set(GPIOC, GPIO_AF_10, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
rcu_periph_clock_enable(RCU_GPIOH);
rcu_periph_clock_enable(RCU_GPIOG);
/* ULPI_STP(PH2) GPIO pin configuration */
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_2);
/* ULPI_CK(PH5) GPIO pin configuration */
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_5);
/* ULPI_NXT(PH4) GPIO pin configuration */
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_4);
/* ULPI_DIR(PH3) GPIO pin configuration */
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_3);
/* ULPI_D0(PH6) GPIO pin configuration */
/* ULPI_D1(PH7), ULPI_D2(PH8), ULPI_D3(PH9), ULPI_D4(PH10) \
ULPI_D5(PH11), ULPI_D6(PH12) and ULPI_D7(PG5) GPIO pin configuration */
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE,
GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 |
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ,
GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 |
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_5);
gpio_af_set(GPIOG, GPIO_AF_8, GPIO_PIN_5);
gpio_af_set(GPIOH, GPIO_AF_8, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
#endif /* USE_USBHS1 */
}
extern usb_core_driver gd_usb_core;
#ifdef USE_USBHS0
/*!
\brief this function handles USBHS0 interrupt
\param[in] none
\param[out] none
\retval none
*/
void USBHS0_IRQHandler(void)
{
rt_interrupt_enter();
#if defined(RT_USING_USB_DEVICE)
usbd_isr(&gd_usb_core);
#else
usbh_isr(&gd_usb_core);
#endif
rt_interrupt_leave();
}
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
/*!
\brief this function handles USBHS1 interrupt
\param[in] none
\param[out] none
\retval none
*/
void USBHS1_IRQHandler(void)
{
rt_interrupt_enter();
#if defined(RT_USING_USB_DEVICE)
usbd_isr(&gd_usb_core);
#else
usbh_isr(&gd_usb_core);
#endif
rt_interrupt_leave();
}
#endif /* USE_USBHS1 */
/*!
\brief resume MCU clock
\param[in] none
\param[out] none
\retval none
*/
static void resume_mcu_clk(void)
{
/* enable HXTAL */
rcu_osci_on(RCU_HXTAL);
/* wait till HXTAL is ready */
while (RESET == rcu_flag_get(RCU_FLAG_HXTALSTB))
{
}
/* enable PLL */
rcu_osci_on(RCU_PLL0_CK);
/* wait till PLL is ready */
while (RESET == rcu_flag_get(RCU_FLAG_PLL0STB))
{
}
/* select PLL as system clock source */
rcu_system_clock_source_config(RCU_CKSYSSRC_PLL0P);
/* wait till PLL is used as system clock source */
while (RCU_SCSS_PLL0P != rcu_system_clock_source_get())
{
}
}
#ifdef USE_USBHS0
/*!
\brief this function handles USBHS0 wakeup interrupt request
\param[in] none
\param[out] none
\retval none
*/
void USBHS0_WKUP_IRQHandler(void)
{
rt_interrupt_enter();
if (gd_usb_core.bp.low_power)
{
resume_mcu_clk();
#ifndef USE_IRC48M
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLL0R);
#else
/* enable IRC48M clock */
rcu_osci_on(RCU_IRC48M);
/* wait till IRC48M is ready */
while (SUCCESS != rcu_osci_stab_wait(RCU_IRC48M))
{
}
rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M);
#endif /* USE_IRC48M */
rcu_periph_clock_enable(RCU_USBHS0);
usb_clock_active(&gd_usb_core);
}
exti_interrupt_flag_clear(EXTI_31);
rt_interrupt_leave();
}
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
/*!
\brief this function handles USBHS1 wakeup interrupt request
\param[in] none
\param[out] none
\retval none
*/
void USBHS1_WKUP_IRQHandler(void)
{
rt_interrupt_enter();
if (gd_usb_core.bp.low_power)
{
resume_mcu_clk();
#ifndef USE_IRC48M
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLL0R);
#else
/* enable IRC48M clock */
rcu_osci_on(RCU_IRC48M);
/* wait till IRC48M is ready */
while (SUCCESS != rcu_osci_stab_wait(RCU_IRC48M))
{
}
rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M);
#endif /* USE_IRC48M */
rcu_periph_clock_enable(RCU_USBHS1);
usb_clock_active(&gd_usb_core);
}
exti_interrupt_flag_clear(EXTI_32);
rt_interrupt_leave();
}
#endif /* USE_USBHS1 */
#ifdef USB_DEDICATED_EP1_ENABLED
#ifdef USE_USBHS0
/*!
\brief this function handles USBHS0 dedicated endpoint 1 OUT interrupt request.
\param[in] none
\param[out] none
\retval none
*/
void USBHS0_EP1_OUT_IRQHandler(void)
{
usbd_int_dedicated_ep1out(&cdc_acm);
}
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
/*!
\brief this function handles USBHS1 dedicated endpoint 1 OUT interrupt request.
\param[in] none
\param[out] none
\retval none
*/
void USBHS1_EP1_OUT_IRQHandler(void)
{
usbd_int_dedicated_ep1out(&cdc_acm);
}
#endif /* USE_USBHS1 */
#ifdef USE_USBHS0
/*!
\brief this function handles USBHS0 dedicated endpoint 1 IN interrupt request
\param[in] none
\param[out] none
\retval none
*/
void USBHS0_EP1_IN_IRQHandler(void)
{
usbd_int_dedicated_ep1in(&cdc_acm);
}
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
/*!
\brief this function handles USBHS1 dedicated endpoint 1 IN interrupt request
\param[in] none
\param[out] none
\retval none
*/
void USBHS1_EP1_IN_IRQHandler(void)
{
usbd_int_dedicated_ep1in(&cdc_acm);
}
#endif /* USE_USBHS1 */
#endif /* USB_DEDICATED_EP1_ENABLED */
/*!
\brief configure USB clock
\param[in] none
\param[out] none
\retval none
*/
void usb_rcu_config(void)
{
pmu_usb_regulator_enable();
pmu_usb_voltage_detector_enable();
while (SET != pmu_flag_get(PMU_FLAG_USB33RF))
{
}
#ifdef USE_USB_FS
#ifndef USE_IRC48M
/* configure the pll1 input and output clock range */
rcu_pll_input_output_clock_range_config(IDX_PLL1, RCU_PLL1RNG_4M_8M, RCU_PLL1VCO_192M_836M);
rcu_pll1_config(5, 96, 2, 10, 2);
/* enable PLL1Q clock output */
rcu_pll_clock_output_enable(RCU_PLL1Q);
rcu_osci_on(RCU_PLL1_CK);
#ifdef USE_USBHS0
rcu_usbhs_pll1qpsc_config(IDX_USBHS0, RCU_USBHSPSC_DIV1);
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLL1Q);
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
rcu_usbhs_pll1qpsc_config(IDX_USBHS1, RCU_USBHSPSC_DIV1);
rcu_usb48m_clock_config(IDX_USBHS1, RCU_USB48MSRC_PLL1Q);
#endif /* USE_USBHS1 */
#else
/* enable IRC48M clock */
rcu_osci_on(RCU_IRC48M);
/* wait till IRC48M is ready */
while (SUCCESS != rcu_osci_stab_wait(RCU_IRC48M))
{
}
rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M);
#ifdef USE_USBHS0
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_IRC48M);
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
rcu_usb48m_clock_config(IDX_USBHS1, RCU_USB48MSRC_IRC48M);
#endif /* USE_USBHS1 */
#endif /* USE_IRC48M */
#endif /* USE_USB_FS */
#ifdef USE_USBHS0
rcu_periph_clock_enable(RCU_USBHS0);
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
rcu_periph_clock_enable(RCU_USBHS1);
#endif /* USE_USBHS1 */
#ifdef USE_ULPI_PHY
#ifdef USE_USBHS0
rcu_periph_clock_enable(RCU_USBHS0ULPI);
#endif
#ifdef USE_USBHS1
rcu_periph_clock_enable(RCU_USBHS1ULPI);
#endif
#endif /* USE_ULPI_PHY */
}
/*!
\brief configure USB interrupt
\param[in] none
\param[out] none
\retval none
*/
void usb_intr_config(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
#ifdef USE_USBHS0
nvic_irq_enable((uint8_t)USBHS0_IRQn, 3U, 0U);
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
nvic_irq_enable((uint8_t)USBHS1_IRQn, 3U, 0U);
#endif /* USE_USBHS0 */
/* enable the power module clock */
rcu_periph_clock_enable(RCU_PMU);
#ifdef USE_USBHS0
/* USB wakeup EXTI line configuration */
exti_interrupt_flag_clear(EXTI_31);
exti_init(EXTI_31, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_enable(EXTI_31);
nvic_irq_enable((uint8_t)USBHS0_WKUP_IRQn, 1U, 0U);
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
/* USB wakeup EXTI line configuration */
exti_interrupt_flag_clear(EXTI_32);
exti_init(EXTI_32, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_enable(EXTI_32);
nvic_irq_enable((uint8_t)USBHS1_WKUP_IRQn, 1U, 0U);
#endif /* USE_USBHS1 */
#ifdef USB_DEDICATED_EP1_ENABLED
#ifdef USE_USBHS0
nvic_irq_enable((uint8_t)USBHS0_EP1_OUT_IRQn, 1U, 0U);
nvic_irq_enable((uint8_t)USBHS0_EP1_IN_IRQn, 1U, 0U);
#endif /* USE_USBHS0 */
#ifdef USE_USBHS1
nvic_irq_enable((uint8_t)USBHS1_EP1_OUT_IRQn, 1U, 0U);
nvic_irq_enable((uint8_t)USBHS1_EP1_IN_IRQn, 1U, 0U);
#endif /* USE_USBHS1 */
#endif /* USB_DEDICATED_EP1_ENABLED */
}
#if defined(RT_USING_USB_HOST)
/*!
\brief drives the VBUS signal through GPIO
\param[in] state: VBUS states
\param[out] none
\retval none
*/
void usb_vbus_drive(uint8_t state)
{
if (0U == state)
{
/* disable is needed on output of the power switch */
gpio_bit_reset(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
}
else
{
/* enable the power switch by driving the enable high */
gpio_bit_set(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
}
}
/*!
\brief configures the GPIO for the VBUS
\param[in] none
\param[out] none
\retval none
*/
void usb_vbus_config(void)
{
rcu_periph_clock_enable(HOST_POWERSW_PORT_RCC);
/* USBFS_VBUS_CTRL(PD13) GPIO pin configuration */
gpio_mode_set(HOST_POWERSW_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HOST_POWERSW_VBUS);
gpio_output_options_set(HOST_POWERSW_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, HOST_POWERSW_VBUS);
/* by default, disable is needed on output of the power switch */
usb_vbus_drive(0U);
/* delay is need for stabilizing the VBUS low in reset condition,
* when VBUS = 1 and reset-button is pressed by user
*/
usb_mdelay(200);
}
#endif
#if defined(BSP_USING_TIMER2) && defined(BSP_USING_USB)
#error "Timer2 has been occupied by USB. Please select another timer resource."
#endif
/*!
\brief initializes delay unit using Timer2
\param[in] none
\param[out] none
\retval none
*/
void usb_timer_init(void)
{
/* configure the priority group to 2 bits */
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
/* enable the TIM2 global interrupt */
nvic_irq_enable((uint8_t)TIMER2_IRQn, 1U, 0U);
rcu_periph_clock_enable(RCU_TIMER2);
}
/*!
\brief delay in microseconds
\param[in] usec: value of delay required in microseconds
\param[out] none
\retval none
*/
void usb_udelay(const uint32_t usec)
{
hw_delay(usec, TIM_USEC_DELAY);
}
/*!
\brief delay in milliseconds
\param[in] msec: value of delay required in milliseconds
\param[out] none
\retval none
*/
void usb_mdelay(const uint32_t msec)
{
hw_delay(msec, TIM_MSEC_DELAY);
}
/*!
\brief time base IRQ
\param[in] none
\param[out] none
\retval none
*/
void usb_timer_irq(void)
{
if (RESET != timer_interrupt_flag_get(TIMER2, TIMER_INT_UP))
{
timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP);
if (delay_time > 0x00U)
{
delay_time--;
}
else
{
timer_disable(TIMER2);
}
}
}
void TIMER2_IRQHandler(void)
{
rt_interrupt_enter();
usb_timer_irq();
rt_interrupt_leave();
}
/*!
\brief delay routine based on TIMER2
\param[in] ntime: delay Time
\param[in] unit: delay Time unit = miliseconds / microseconds
\param[out] none
\retval none
*/
static void hw_delay(uint32_t ntime, uint8_t unit)
{
delay_time = ntime;
hw_time_set(unit);
while (0U != delay_time)
{
}
timer_disable(TIMER2);
}
/*!
\brief configures TIMER2 for delay routine based on TIMER2
\param[in] unit: msec /usec
\param[out] none
\retval none
*/
static void hw_time_set(uint8_t unit)
{
timer_parameter_struct timer_basestructure;
timer_disable(TIMER2);
timer_interrupt_disable(TIMER2, TIMER_INT_UP);
if (TIM_USEC_DELAY == unit)
{
timer_basestructure.period = 9U;
}
else if (TIM_MSEC_DELAY == unit)
{
timer_basestructure.period = 9999U;
}
else
{
/* no operation */
}
timer_basestructure.prescaler = timer_prescaler;
timer_basestructure.alignedmode = TIMER_COUNTER_EDGE;
timer_basestructure.counterdirection = TIMER_COUNTER_UP;
timer_basestructure.clockdivision = TIMER_CKDIV_DIV1;
timer_basestructure.repetitioncounter = 0U;
timer_init(TIMER2, &timer_basestructure);
timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP);
timer_auto_reload_shadow_enable(TIMER2);
/* TIMER IT enable */
timer_interrupt_enable(TIMER2, TIMER_INT_UP);
/* TIMER2 enable counter */
timer_enable(TIMER2);
}
/*!
\brief configure the PLL of USB
\param[in] usb_periph: USBHS0 or USBHS1
\param[out] none
\retval none
*/
void pllusb_rcu_config(uint32_t usb_periph)
{
if (USBHS0 == usb_periph)
{
rcu_pllusb0_config(RCU_PLLUSBHSPRE_HXTAL, RCU_PLLUSBHSPRE_DIV5, RCU_PLLUSBHS_MUL96, RCU_USBHS_DIV8);
RCU_ADDCTL1 |= RCU_ADDCTL1_PLLUSBHS0EN;
while (0U == (RCU_ADDCTL1 & RCU_ADDCTL1_PLLUSBHS0STB))
{
}
rcu_usbhs_clock_selection_enable(IDX_USBHS0);
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLLUSBHS);
rcu_usbhs_clock_config(IDX_USBHS0, RCU_USBHSSEL_60M);
}
else
{
rcu_pllusb1_config(RCU_PLLUSBHSPRE_HXTAL, RCU_PLLUSBHSPRE_DIV5, RCU_PLLUSBHS_MUL96, RCU_USBHS_DIV8);
RCU_ADDCTL1 |= RCU_ADDCTL1_PLLUSBHS1EN;
while (0U == (RCU_ADDCTL1 & RCU_ADDCTL1_PLLUSBHS1STB))
{
}
rcu_usbhs_clock_selection_enable(IDX_USBHS1);
rcu_usb48m_clock_config(IDX_USBHS1, RCU_USB48MSRC_PLLUSBHS);
rcu_usbhs_clock_config(IDX_USBHS1, RCU_USBHSSEL_60M);
}
}
#endif /* BSP_USING_USB */

405
828ECO/libraries/CMSIS/GD/GD32H75E/Include/gd32h75e.h

@ -0,0 +1,405 @@
/*!
\file gd32h75e.h
\brief general definitions for GD32H75e
\version 2025-01-24, V1.1.0, firmware for GD32H75E
*/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
* Copyright (c) 2025, GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
#ifndef GD32H75E_H
#define GD32H75E_H
#ifdef __cplusplus
extern "C" {
#endif
#if !defined (GD32H75E)
#error "Please select the target GD32H75E device used in your application (in gd32h75e.h file)"
#endif /* undefine GD32H75E tip */
/* define value of high speed crystal oscillator (HXTAL) in Hz */
#if !defined (HXTAL_VALUE)
#define HXTAL_VALUE ((uint32_t)25000000)
#endif /* high speed crystal oscillator value */
/* define startup timeout value of high speed crystal oscillator (HXTAL) */
#if !defined (HXTAL_STARTUP_TIMEOUT)
#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0FFFF)
#endif /* high speed crystal oscillator startup timeout */
/* define value of internal 64MHz RC oscillator (IRC64M) in Hz */
#if !defined (IRC64M_VALUE)
#define IRC64M_VALUE ((uint32_t)64000000)
#endif /* internal 64MHz RC oscillator value */
/* define startup timeout value of internal 64MHz RC oscillator (IRC64M) */
#if !defined (IRC64M_STARTUP_TIMEOUT)
#define IRC64M_STARTUP_TIMEOUT ((uint16_t)0x0500)
#endif /* internal 64MHz RC oscillator startup timeout */
/* define value of Low Power Internal 4Mhz RC oscillator (LPIRC4M) in Hz */
#if !defined (LPIRC4M_VALUE)
#define LPIRC4M_VALUE ((uint32_t)4000000)
#endif /* Low Power Internal 4Mhz RC oscillator value */
/* define startup timeout value of internal Low Power Internal 4Mhz RC oscillator (LPIRC4M) */
#if !defined (LPIRC4M_STARTUP_TIMEOUT)
#define LPIRC4M_STARTUP_TIMEOUT ((uint16_t)0x0500)
#endif /* Low Power Internal 4Mhz RC oscillator startup timeout */
/* define value of internal 48MHz RC oscillator (IRC48M) in Hz */
#if !defined (IRC48M_VALUE)
#define IRC48M_VALUE ((uint32_t)48000000)
#endif /* internal 48MHz RC oscillator value */
/* define startup timeout value of internal 48MHz RC oscillator (IRC48M) */
#if !defined (IRC48M_STARTUP_TIMEOUT)
#define IRC48M_STARTUP_TIMEOUT ((uint16_t)0x0500)
#endif /* internal 48MHz RC oscillator startup timeout */
/* define value of internal 32KHz RC oscillator(IRC32K) in Hz */
#if !defined (IRC32K_VALUE)
#define IRC32K_VALUE ((uint32_t)32000)
#endif /* internal 32KHz RC oscillator value */
/* define startup timeout value of internal 32KHz RC oscillator (IRC32K) */
#if !defined (IRC32K_STARTUP_TIMEOUT)
#define IRC32K_STARTUP_TIMEOUT ((uint16_t)0x0500)
#endif /* internal 32KHz RC oscillator startup timeout */
/* define value of low speed crystal oscillator (LXTAL)in Hz */
#if !defined (LXTAL_VALUE)
#define LXTAL_VALUE ((uint32_t)32768)
#endif /* low speed crystal oscillator value */
/* define startup timeout value of low speed crystal oscillator (LXTAL) */
#if !defined (LXTAL_STARTUP_TIMEOUT)
#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x0FFFFFFF)
#endif /* low speed crystal oscillator startup timeout */
/* GD32H75E firmware library version number V1.1.0 */
#define __GD32H75E_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */
#define __GD32H75E_STDPERIPH_VERSION_SUB1 (0x01) /*!< [23:16] sub1 version */
#define __GD32H75E_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
#define __GD32H75E_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */
#define __GD32H75E_STDPERIPH_VERSION ((__GD32H75E_STDPERIPH_VERSION_MAIN << 24)\
|(__GD32H75E_STDPERIPH_VERSION_SUB1 << 16)\
|(__GD32H75E_STDPERIPH_VERSION_SUB2 << 8)\
|(__GD32H75E_STDPERIPH_VERSION_RC))
/* configuration of the Cortex-M7 processor and core peripherals */
#define __CM7_REV 0x0102U /*!< Cortex-M7 revision r1p2 */
#define __MPU_PRESENT 1 /*!< CM7 provides an MPU */
#define __NVIC_PRIO_BITS 4 /*!< CM7 uses 4 Bits for the Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
#define __FPU_PRESENT 1 /*!< FPU present */
#define __ICACHE_PRESENT 1 /*!< CM7 instruction cache present */
#define __DCACHE_PRESENT 1 /*!< CM7 data cache present */
/* define interrupt number */
typedef enum IRQn {
/* Cortex-M7 processor exceptions numbers */
NonMaskableInt_IRQn = -14, /*!< non mask-able interrupt */
HardFault_IRQn = -13, /*!< hard-fault interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M7 memory management interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M7 bus fault interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M7 usage fault interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M7 sv call interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M7 debug monitor interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M7 pend sv interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M7 system tick interrupt */
/* interruput numbers */
WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */
VAVD_LVD_VOVD_IRQn = 1, /*!< AVD_LVD_OVD_IRQn through EXTI line detect interrupt */
TAMPER_STAMP_LXTAL_IRQn = 2, /*!< RTC tamper and timestamp interrupt/LXTAL clock stuck interrupt */
RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt */
FMC_IRQn = 4, /*!< FMC interrupt */
RCU_IRQn = 5, /*!< RCU interrupt */
EXTI0_IRQn = 6, /*!< EXTI line 0 */
EXTI1_IRQn = 7, /*!< EXTI line 1 */
EXTI2_IRQn = 8, /*!< EXTI line 2 */
EXTI3_IRQn = 9, /*!< EXTI line 3 */
EXTI4_IRQn = 10, /*!< EXTI line 4 */
DMA0_Channel0_IRQn = 11, /*!< DMA0 channel 0 interrupt */
DMA0_Channel1_IRQn = 12, /*!< DMA0 channel 1 interrupt */
DMA0_Channel2_IRQn = 13, /*!< DMA0 channel 2 interrupt */
DMA0_Channel3_IRQn = 14, /*!< DMA0 channel 3 interrupt */
DMA0_Channel4_IRQn = 15, /*!< DMA0 channel 4 interrupt */
DMA0_Channel5_IRQn = 16, /*!< DMA0 channel 5 interrupt */
DMA0_Channel6_IRQn = 17, /*!< DMA0 channel 6 interrupt */
ADC0_1_IRQn = 18, /*!< ADC0 and ADC1 */
EXTI5_9_IRQn = 23, /*!< EXTI line 5 to 9 */
TIMER0_BRK_IRQn = 24, /*!< TIMER0 break interrupt */
TIMER0_UP_IRQn = 25, /*!< TIMER0 update interrupt */
TIMER0_TRG_CMT_IRQn = 26, /*!< TIMER0 trigger/commutation interrupt */
TIMER0_Channel_IRQn = 27, /*!< TIMER0 capture/compare interrupt */
TIMER1_IRQn = 28, /*!< TIMER1 interrupt */
TIMER2_IRQn = 29, /*!< TIMER2 interrupt */
TIMER3_IRQn = 30, /*!< TIMER3 interrupt */
I2C0_EV_IRQn = 31, /*!< I2C0 event interrupt */
I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */
I2C1_EV_IRQn = 33, /*!< I2C1 event interrupt */
I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */
SPI0_IRQn = 35, /*!< SPI0 interrupt */
SPI1_IRQn = 36, /*!< SPI1 interrupt */
USART0_IRQn = 37, /*!< USART0 global and wakeup interrupt */
USART1_IRQn = 38, /*!< USART1 global and wakeup interrupt */
USART2_IRQn = 39, /*!< USART2 global and wakeup interrupt */
EXTI10_15_IRQn = 40, /*!< EXTI line 10 to 15 */
RTC_Alarm_IRQn = 41, /*!< RTC Alarm interrupt */
TIMER7_BRK_IRQn = 43, /*!< TIMER7 Break global interrupt */
TIMER7_UP_IRQn = 44, /*!< TIMER7 Update global interrupt */
TIMER7_TRG_CMT_IRQn = 45, /*!< TIMER7 Trigger and Commutation global interrupt */
TIMER7_Channel_IRQn = 46, /*!< TIMER7 Capture Compare interrupt */
DMA0_Channel7_IRQn = 47, /*!< DMA0 channel 7 interrupt */
EXMC_IRQn = 48, /*!< EXMC interrupt */
SDIO0_IRQn = 49, /*!< SDMMC0 interrupt */
TIMER4_IRQn = 50, /*!< TIMER4 interrupt */
SPI2_IRQn = 51, /*!< SPI2 interrupt */
UART3_IRQn = 52, /*!< UART3 interrupt */
UART4_IRQn = 53, /*!< UART4 interrupt */
TIMER5_DAC_UDR_IRQn = 54, /*!< TIMER5 global interrupt and DAC1/DAC0 underrun */
TIMER6_IRQn = 55, /*!< TIMER6 interrupt */
DMA1_Channel0_IRQn = 56, /*!< DMA1 channel0 interrupt */
DMA1_Channel1_IRQn = 57, /*!< DMA1 channel1 interrupt */
DMA1_Channel2_IRQn = 58, /*!< DMA1 channel2 interrupt */
DMA1_Channel3_IRQn = 59, /*!< DMA1 channel3 interrupt */
DMA1_Channel4_IRQn = 60, /*!< DMA1 channel4 interrupt */
ENET0_IRQn = 61, /*!< ENET 0 interrupt */
ENET0_WKUP_IRQn = 62, /*!< ENET 0 wakeup through EXTI line interrupt */
DMA1_Channel5_IRQn = 68, /*!< DMA1 channel 5 interrupt */
DMA1_Channel6_IRQn = 69, /*!< DMA1 channel 6 interrupt */
DMA1_Channel7_IRQn = 70, /*!< DMA1 channel 7 interrupt */
USART5_IRQn = 71, /*!< UART5 global and wakeup interrupt */
I2C2_EV_IRQn = 72, /*!< I2C2 event interrupt */
I2C2_ER_IRQn = 73, /*!< I2C2 error interrupt */
USBHS0_EP1_OUT_IRQn = 74, /*!< USBHS0 endpoint 1 out interrupt */
USBHS0_EP1_IN_IRQn = 75, /*!< USBHS0 endpoint 1 in interrupt */
USBHS0_WKUP_IRQn = 76, /*!< USBHS0 wakeup through EXTI line interrupt */
USBHS0_IRQn = 77, /*!< USBHS0 interrupt */
DCI_IRQn = 78, /*!< DCI interrupt */
CAU_IRQn = 79, /*!< CAU interrupt */
HAU_TRNG_IRQn = 80, /*!< HAU and TRNG interrupt */
FPU_IRQn = 81, /*!< FPU interrupt */
UART6_IRQn = 82, /*!< UART6 interrupt */
UART7_IRQn = 83, /*!< UART7 interrupt */
SPI3_IRQn = 84, /*!< SPI3 interrupt */
SPI4_IRQn = 85, /*!< SPI4 interrupt */
SPI5_IRQn = 86, /*!< SPI5 interrupt */
SAI0_IRQn = 87, /*!< SAI0 interrupt */
TLI_IRQn = 88, /*!< TLI interrupt */
TLI_ER_IRQn = 89, /*!< TLI error interrupt */
IPA_IRQn = 90, /*!< IPA interrupt */
SAI1_IRQn = 91, /*!< SAI1 interrupt */
OSPI0_IRQn = 92, /*!< OSPI0 global interrupt */
I2C3_EV_IRQn = 95, /*!< I2C3 event interrupt */
I2C3_ER_IRQn = 96, /*!< I2C3 error interrupt */
RSPDIF_IRQn = 97, /*!< RSPDIF global interrupt */
DMAMUX_OVR_IRQn = 102, /*!< DMAMUX overrun interrupt */
HPDF_INT0_IRQn = 110, /*!< HPDF filiter 0 interrupt */
HPDF_INT1_IRQn = 111, /*!< HPDF filiter 1 interrupt */
HPDF_INT2_IRQn = 112, /*!< HPDF filiter 2 interrupt */
HPDF_INT3_IRQn = 113, /*!< HPDF filiter 3 interrupt */
SAI2_IRQn = 114, /*!< SAI2 interrupt */
TIMER14_IRQn = 116, /*!< TIMER14 interrupt */
TIMER15_IRQn = 117, /*!< TIMER15 interrupt */
TIMER16_IRQn = 118, /*!< TIMER16 interrupt */
MDIO_IRQn = 120, /*!< MDIO interrupt */
MDMA_IRQn = 122, /*!< MDMA interrupt */
SDIO1_IRQn = 124, /*!< SDIO1 interrupt */
HWSEM_IRQn = 125, /*!< HWSEM interrupt */
ADC2_IRQn = 127, /*!< ADC2 interrupt */
CMP0_1_IRQn = 137, /*!< CMP0 and CMP1 interrupt */
CTC_IRQn = 144, /*!< CTC interrupt */
RAMECCMU_IRQn = 145, /*!< RAMECCMU interrupt */
OSPI1_IRQn = 150, /*!< OSPI1 interrupt */
RTDEC0_IRQn = 151, /*!< RTDEC0 interrupt */
RTDEC1_IRQn = 152, /*!< RTDEC1 interrupt */
FAC_IRQn = 153, /*!< FAC interrupt */
TMU_IRQn = 154, /*!< TMU interrupt */
TIMER22_IRQn = 161, /*!< TIMER22 interrupt */
TIMER23_IRQn = 162, /*!< TIMER23 interrupt */
TIMER40_IRQn = 165, /*!< TIMER40 interrupt */
TIMER41_IRQn = 166, /*!< TIMER41 interrupt */
TIMER42_IRQn = 167, /*!< TIMER42 interrupt */
TIMER43_IRQn = 168, /*!< TIMER43 interrupt */
TIMER44_IRQn = 169, /*!< TIMER44 interrupt */
TIMER50_IRQn = 170, /*!< TIMER50 interrupt */
TIMER51_IRQn = 171, /*!< TIMER51 interrupt */
USBHS1_EP1_OUT_IRQn = 172, /*!< USBHS1 endpoint 1 out interrupt */
USBHS1_EP1_IN_IRQn = 173, /*!< USBHS1 endpoint 1 in interrupt */
USBHS1_WKUP_IRQn = 174, /*!< USBHS1 wakeup through EXTI line interrupt */
USBHS1_IRQn = 175, /*!< USBHS1 interrupt */
ENET1_IRQn = 176, /*!< ENET1 interrupt */
ENET1_WKUP_IRQn = 177, /*!< ENET1 wakeup through EXTI line interrupt */
CAN0_WKUP_IRQn = 179, /*!< CAN 0 wakeup through EXTI line interrupt */
CAN0_Message_IRQn = 180, /*!< CAN 0 message buffer interrupt */
CAN0_Busoff_IRQn = 181, /*!< CAN 0 bus off / bus off done interrupt */
CAN0_Error_IRQn = 182, /*!< CAN 0 error interrupt */
CAN0_FastError_IRQn = 183, /*!< CAN 0 error in fast transmission interrupt */
CAN0_TEC_IRQn = 184, /*!< CAN 0 transmit warning interrupt */
CAN0_REC_IRQn = 185, /*!< CAN 0 receive warning interrupt */
CAN1_WKUP_IRQn = 186, /*!< CAN 1 wakeup through EXTI line interrupt */
CAN1_Message_IRQn = 187, /*!< CAN 1 message buffer interrupt */
CAN1_Busoff_IRQn = 188, /*!< CAN 1 bus off / bus off done interrupt */
CAN1_Error_IRQn = 189, /*!< CAN 1 error interrupt */
CAN1_FastError_IRQn = 190, /*!< CAN 1 error in fast transmission interrupt */
CAN1_TEC_IRQn = 191, /*!< CAN 1 transmit warning interrupt */
CAN1_REC_IRQn = 192, /*!< CAN 1 receive warning interrupt */
CAN2_WKUP_IRQn = 193, /*!< CAN 2 wakeup through EXTI line interrupt */
CAN2_Message_IRQn = 194, /*!< CAN 2 message buffer interrupt */
CAN2_Busoff_IRQn = 195, /*!< CAN 2 bus off / bus off done interrupt */
CAN2_Error_IRQn = 196, /*!< CAN 2 error interrupt */
CAN2_FastError_IRQn = 197, /*!< CAN 2 error in fast transmission interrupt */
CAN2_TEC_IRQn = 198, /*!< CAN 2 transmit warning interrupt */
CAN2_REC_IRQn = 199, /*!< CAN 2 receive warning interrupt */
EFUSE_IRQn = 200, /*!< EFUSE interrupt */
I2C0_WKUP_IRQn = 201, /*!< I2C 0 wakeup through EXTI line interrupt */
I2C1_WKUP_IRQn = 202, /*!< I2C 1 wakeup through EXTI line interrupt */
I2C2_WKUP_IRQn = 203, /*!< I2C 2 wakeup through EXTI line interrupt */
I2C3_WKUP_IRQn = 204, /*!< I2C 3 wakeup through EXTI line interrupt */
LPDTS_IRQn = 205, /*!< LPDTS interrupt */
LPDTS_WKUP_IRQn = 206, /*!< LPDTS wakeup through EXTI line interrupt */
TIMER0_DEC_IRQn = 207, /*!< TIMER0 DEC interrupt */
TIMER7_DEC_IRQn = 208, /*!< TIMER7 DEC interrupt */
TIMER1_DEC_IRQn = 209, /*!< TIMER1 DEC interrupt */
TIMER2_DEC_IRQn = 210, /*!< TIMER2 DEC interrupt */
TIMER3_DEC_IRQn = 211, /*!< TIMER3 DEC interrupt */
TIMER4_DEC_IRQn = 212, /*!< TIMER4 DEC interrupt */
TIMER22_DEC_IRQn = 213, /*!< TIMER22 DEC interrupt */
TIMER23_DEC_IRQn = 214, /*!< TIMER23 DEC interrupt */
} IRQn_Type;
/* includes */
#include "core_cm7.h"
#include "system_gd32h75e.h"
#include <stdint.h>
#ifdef FW_DEBUG_ERR_REPORT
#include "gd32h75e_err_report.h"
#endif /* FW_DEBUG_ERR_REPORT */
/* enum definitions */
typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
typedef enum {RESET = 0, SET = !RESET} FlagStatus;
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus;
/* bit operations */
#define REG64(addr) (*(volatile uint64_t *)(uint32_t)(addr))
#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr))
#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr))
#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr))
#define BIT(x) ((uint32_t)((uint32_t)0x01U << (x)))
#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end))))
#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start))
/* main flash and SRAM memory map */
#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */
#define SRAM_BASE ((uint32_t)0x24000000U) /*!< SRAM base address */
/* SRAM and peripheral base bit-band region */
#define SRAM_BB_BASE ((uint32_t)0x22000000U) /*!< SRAM bit-band base address */
#define PERIPH_BB_BASE ((uint32_t)0x42000000U) /*!< peripheral bit-band base address */
/* peripheral memory map */
#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */
#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */
#define APB3_BUS_BASE ((uint32_t)0x50000000U) /*!< apb3 base address */
#define APB4_BUS_BASE ((uint32_t)0x58000000U) /*!< apb4 base address */
#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */
#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */
#define AHB3_BUS_BASE ((uint32_t)0x51000000U) /*!< ahb3 base address */
#define AHB4_BUS_BASE ((uint32_t)0x58020000U) /*!< ahb4 base address */
/* advanced peripheral bus 1 memory map */
#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */
#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */
#define RSPDIF_BASE (APB1_BUS_BASE + 0x00004000U) /*!< RSPDIF base address */
#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */
#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */
#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */
#define CTC_BASE (APB1_BUS_BASE + 0x00008400U) /*!< CTC base address */
#define MDIO_BASE (APB1_BUS_BASE + 0x00009400U) /*!< MDIO base address */
/* advanced peripheral bus 2 memory map */
#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */
#define SAI_BASE (APB2_BUS_BASE + 0x00005800U) /*!< SAI base address */
#define HPDF_BASE (APB2_BUS_BASE + 0x00007000U) /*!< HPDF base address */
#define TRIGSEL_BASE (APB2_BUS_BASE + 0x00008400U) /*!< TRIGSEL base address */
#define EDOUT_BASE (APB2_BUS_BASE + 0x00008800U) /*!< EDOUT base address */
#define CAN_BASE (APB2_BUS_BASE + 0x0000A000U) /*!< CAN base address */
/* advanced peripheral bus 3 memory map */
#define TLI_BASE (APB3_BUS_BASE + 0x00001000U) /*!< TLI base address */
#define WWDGT_BASE (APB3_BUS_BASE + 0x00003000U) /*!< WWDGT base address */
/* advanced peripheral bus 4 memory map */
#define EXTI_BASE (APB4_BUS_BASE + 0x00000000U) /*!< EXTI base address */
#define SYSCFG_BASE (APB4_BUS_BASE + 0x00000400U) /*!< SYSCFG base address */
#define CMP_BASE (APB4_BUS_BASE + 0x00003800U) /*!< CMP base address */
#define VREF_BASE (APB4_BUS_BASE + 0x00003C00U) /*!< VREF base address */
#define RTC_BASE (APB4_BUS_BASE + 0x00004000U) /*!< CMP base address */
#define FWDGT_BASE (APB4_BUS_BASE + 0x00004800U) /*!< FWDGT base address */
#define PMU_BASE (APB4_BUS_BASE + 0x00005800U) /*!< PMU base address */
#define LPDTS_BASE (APB4_BUS_BASE + 0x00006800U) /*!< LPDTS base address */
/* advanced high performance bus 1 memory map */
#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */
#define DMAMUX_BASE (AHB1_BUS_BASE + 0x00000800U) /*!< DMAMUX base address */
#define EFUSE_BASE (AHB1_BUS_BASE + 0x00002800U) /*!< EFUSE base address */
#define ENET_BASE (AHB1_BUS_BASE + 0x00008000U) /*!< ENET base address */
#define USBHS_BASE (AHB1_BUS_BASE + 0x00020000U) /*!< USBHS base address */
/* advanced high performance bus 2 memory map */
#define DCI_BASE (AHB2_BUS_BASE + 0x00020000U) /*!< DCI base address */
#define CAU_BASE (AHB2_BUS_BASE + 0x00021000U) /*!< CAU base address */
#define HAU_BASE (AHB2_BUS_BASE + 0x00021400U) /*!< HAU base address */
#define TRNG_BASE (AHB2_BUS_BASE + 0x00021800U) /*!< TRNG base address */
#define SDIO_BASE (AHB2_BUS_BASE + 0x00022400U) /*!< SDIO base address */
#define CPDM_BASE (AHB2_BUS_BASE + 0x00022800U) /*!< CPDM base address */
#define RAMECCMU_BASE (AHB2_BUS_BASE + 0x00023000U) /*!< RAMECCMU base address */
#define TMU_BASE (AHB2_BUS_BASE + 0x00024400U) /*!< TMU base address */
#define FAC_BASE (AHB2_BUS_BASE + 0x00024800U) /*!< FAC base address */
/* advanced high performance bus 3 memory map */
#define AXIM_BASE (AHB3_BUS_BASE + 0x00000000U) /*!< AXIM base address */
#define MDMA_BASE (AHB3_BUS_BASE + 0x01000000U) /*!< MDMA base address */
#define IPA_BASE (AHB3_BUS_BASE + 0x01001000U) /*!< IPA base address */
#define FMC_BASE (AHB3_BUS_BASE + 0x01002000U) /*!< FMC base address */
#define FLEXRAMC_BASE (AHB3_BUS_BASE + 0x01003000U) /*!< FLEXRAMC base address */
#define EXMC_BASE (AHB3_BUS_BASE + 0x01004000U) /*!< EXMC base address */
#define OSPI_BASE (AHB3_BUS_BASE + 0x01005000U) /*!< OSPI base address */
#define OSPM_BASE (AHB3_BUS_BASE + 0x0100B400U) /*!< OSPM base address */
#define RTDEC_BASE (AHB3_BUS_BASE + 0x0100B800U) /*!< RTDEC base address */
/* advanced high performance bus 4 memory map */
#define GPIO_BASE (AHB4_BUS_BASE + 0x00000000U) /*!< GPIO base address */
#define RCU_BASE (AHB4_BUS_BASE + 0x00004400U) /*!< RCU base address */
#define CRC_BASE (AHB4_BUS_BASE + 0x00004C00U) /*!< CRC base address */
#define HWSEM_BASE (AHB4_BUS_BASE + 0x00006400U) /*!< HWSEM base address */
/* option byte and debug memory map */
#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */
#define DBG_BASE ((uint32_t)0xE00E1000U) /*!< DBG base address */
/* define marco USE_STDPERIPH_DRIVER */
#if !defined USE_STDPERIPH_DRIVER
#define USE_STDPERIPH_DRIVER
#endif
#ifdef USE_STDPERIPH_DRIVER
#include "gd32h75e_libopt.h"
#endif /* USE_STDPERIPH_DRIVER */
#ifdef __cplusplus
}
#endif
#endif /* GD32H75E_H */

111
828ECO/libraries/CMSIS/GD/GD32H75E/Include/gd32h75e_err_report.h

@ -0,0 +1,111 @@
/*!
\file gd32h75e_report_err.h
\brief Reporting Error driver
\version 2025-01-24, V1.1.0, firmware for GD32H75E
*/
/*
Copyright (c) 2025, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef HSM_ERR_REPORT_H
#define HSM_ERR_REPORT_H
#include <stdint.h>
/* define the size of the error report buffer */
#define ERR_REPORT_BUFFER_SIZE 60U
/* define the unique identifier of peripherals */
#define SYSCFG_MODULE_ID ((uint8_t)0x01U) /*!< SYSCFG module ID */
#define RAMECCMU_MODULE_ID ((uint8_t)0x02U) /*!< RAMECCMU module ID */
#define FMC_MODULE_ID ((uint8_t)0x03U) /*!< FMC module ID */
#define EFUSE_MODULE_ID ((uint8_t)0x04U) /*!< EFUSE module ID */
#define PMU_MODULE_ID ((uint8_t)0x05U) /*!< PMU module ID */
#define RCU_MODULE_ID ((uint8_t)0x06U) /*!< RCU module ID */
#define CTC_MODULE_ID ((uint8_t)0x07U) /*!< CTC module ID */
#define EXTI_MODULE_ID ((uint8_t)0x08U) /*!< EXTI module ID */
#define TRIGSEL_MODULE_ID ((uint8_t)0x09U) /*!< TRIGSEL module ID */
#define GPIO_MODULE_ID ((uint8_t)0x0AU) /*!< GPIO module ID */
#define CRC_MODULE_ID ((uint8_t)0x0BU) /*!< CRC module ID */
#define TRNG_MODULE_ID ((uint8_t)0x0CU) /*!< TRNG module ID */
#define TMU_MODULE_ID ((uint8_t)0x0DU) /*!< TMU module ID */
#define DMA_DMAMUX_MODULE_ID ((uint8_t)0x0EU) /*!< DMA and DMAMUX module ID */
#define MDMA_MODULE_ID ((uint8_t)0x0FU) /*!< MDMA module ID */
#define DBG_MODULE_ID ((uint8_t)0x10U) /*!< DBG module ID */
#define ADC_MODULE_ID ((uint8_t)0x11U) /*!< ADC module ID */
#define DAC_MODULE_ID ((uint8_t)0x12U) /*!< DAC module ID */
#define FWDGT_MODULE_ID ((uint8_t)0x13U) /*!< FWDGT module ID */
#define WWDGT_MODULE_ID ((uint8_t)0x14U) /*!< WWDGT module ID */
#define RTC_MODULE_ID ((uint8_t)0x15U) /*!< RTC module ID */
#define TIMER_MODULE_ID ((uint8_t)0x16U) /*!< TIMER module ID */
#define USART_MODULE_ID ((uint8_t)0x17U) /*!< USART module ID */
#define I2C_MODULE_ID ((uint8_t)0x18U) /*!< I2C module ID */
#define SPI_MODULE_ID ((uint8_t)0x19U) /*!< SPI module ID */
#define OSPIM_MODULE_ID ((uint8_t)0x1AU) /*!< OSPIM module ID */
#define OSPI_MODULE_ID ((uint8_t)0x1BU) /*!< OSPI module ID */
#define EXMC_MODULE_ID ((uint8_t)0x1CU) /*!< EXMC module ID */
#define VREF_MODULE_ID ((uint8_t)0x1DU) /*!< VREF module ID */
#define LPDTS_MODULE_ID ((uint8_t)0x1EU) /*!< LPDTS module ID */
#define EDOUT_MODULE_ID ((uint8_t)0x1FU) /*!< EDOUT module ID */
#define CAN_MODULE_ID ((uint8_t)0x20U) /*!< CAN module ID */
#define CMP_MODULE_ID ((uint8_t)0x21U) /*!< CMP module ID */
#define HPDF_MODULE_ID ((uint8_t)0x22U) /*!< HPDF module ID */
#define FAC_MODULE_ID ((uint8_t)0x23U) /*!< FAC module ID */
#define MISC_MODULE_ID ((uint8_t)0x24U) /*!< MISC module ID */
#define USBHS_MODULE_ID ((uint8_t)0x25U) /*!< USBHS module ID */
#define ESC_MODULE_ID ((uint8_t)0x26U) /*!< ESC module ID */
/* define the unique identifier of error type */
#define ERR_PERIPH ((uint8_t)0x01U) /*!< peripheral error */
#define ERR_PARAM_POINTER ((uint8_t)0x02U) /*!< invalid pointer */
#define ERR_PARAM_OUT_OF_RANGE ((uint8_t)0x03U) /*!< out of range */
#define ERR_PARAM_INVALID ((uint8_t)0x04U) /*!< invalid parameter */
/* define the unique identifier of API */
#define API_ID(x) ((uint16_t)(x)) /*!< API ID */
/* definitions for parameter checking */
#define NOT_VALID_POINTER(x) ((void *) 0 == (x)) /*!< check the invalid pointer */
/* defining the structure to store the parameters of Report Error function */
typedef struct {
/* module ID where the error occurred */
uint16_t moduleid;
/* API ID associated with the error */
uint16_t apiid;
/* error ID indicating the specific error type */
uint8_t errid;
} err_report_struct;
/* declare external arrays and variables for error reporting */
extern err_report_struct err_report_buffer[ERR_REPORT_BUFFER_SIZE];
/* index to track the next available position in the error report buffer */
extern uint8_t err_report_buff_index;
/* reporting errors in debug mode */
void fw_debug_report_err(uint16_t moduleid, uint16_t apiid, uint8_t errid);
#endif /* ERR_REPORT_H */

76
828ECO/libraries/CMSIS/GD/GD32H75E/Include/gd32h75e_libopt.h

@ -0,0 +1,76 @@
/*!
\file gd32h75e_libopt.h
\brief library optional for gd32h75e
\version 2025-08-07, V1.2.0, firmware for GD32H75E
*/
/*
Copyright (c) 2025, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef GD32H75E_LIBOPT_H
#define GD32H75E_LIBOPT_H
#include "gd32h75e_adc.h"
#include "gd32h75e_axiim.h"
#include "gd32h75e_can.h"
#include "gd32h75e_cmp.h"
#include "gd32h75e_crc.h"
#include "gd32h75e_ctc.h"
#include "gd32h75e_dac.h"
#include "gd32h75e_dbg.h"
#include "gd32h75e_dma.h"
#include "gd32h75e_edout.h"
#include "gd32h75e_efuse.h"
#include "gd32h75e_exmc.h"
#include "gd32h75e_exti.h"
#include "gd32h75e_fac.h"
#include "gd32h75e_fmc.h"
#include "gd32h75e_fwdgt.h"
#include "gd32h75e_gpio.h"
#include "gd32h75e_hpdf.h"
#include "gd32h75e_i2c.h"
#include "gd32h75e_lpdts.h"
#include "gd32h75e_mdma.h"
#include "gd32h75e_misc.h"
#include "gd32h75e_ospi.h"
#include "gd32h75e_ospim.h"
#include "gd32h75e_pmu.h"
#include "gd32h75e_rameccmu.h"
#include "gd32h75e_rcu.h"
#include "gd32h75e_rtc.h"
#include "gd32h75e_spi.h"
#include "gd32h75e_syscfg.h"
#include "gd32h75e_timer.h"
#include "gd32h75e_tmu.h"
#include "gd32h75e_trigsel.h"
#include "gd32h75e_trng.h"
#include "gd32h75e_usart.h"
#include "gd32h75e_vref.h"
#include "gd32h75e_wwdgt.h"
#endif /* GD32H75E_LIBOPT_H */

56
828ECO/libraries/CMSIS/GD/GD32H75E/Include/system_gd32h75e.h

@ -0,0 +1,56 @@
/*!
\file system_gd32h75e.h
\brief CMSIS Cortex-M7 Device Peripheral Access Layer Header File for
gd32h75e Device Series
*/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
* Copyright (c) 2025, GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
#ifndef SYSTEM_GD32H75E_H
#define SYSTEM_GD32H75E_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/* firmware version can be aquired by uncommenting the macro */
#define __FIRMWARE_VERSION_DEFINE
/* system clock frequency (core clock) */
extern uint32_t SystemCoreClock;
/* function declarations */
/* initialize the system and update the SystemCoreClock variable */
extern void SystemInit (void);
/* update the SystemCoreClock with current core clock retrieved from cpu registers */
extern void SystemCoreClockUpdate (void);
#ifdef __FIRMWARE_VERSION_DEFINE
/* get firmware version */
extern uint32_t gd32h75e_firmware_version_get(void);
#endif /* __FIRMWARE_VERSION_DEFINE */
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_GD32H75E_H */

750
828ECO/libraries/CMSIS/GD/GD32H75E/Source/GCC/startup_gd32h75e.s

@ -0,0 +1,750 @@
.syntax unified
.cpu cortex-m7
.fpu softvfp
.thumb
.global Default_Handler
/* necessary symbols defined in linker script to initialize data */
.word _sidata
.word _sdata
.word _edata
.word _sbss
.word _ebss
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
/* reset Handler */
Reset_Handler:
movs r1, #0
b DataInit
CopyData:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
DataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyData
ldr r2, =_sbss
b Zerobss
FillZerobss:
movs r3, #0
str r3, [r2], #4
Zerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call SystemInit function */
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/*Call the main function */
bl entry
bx lr
.size Reset_Handler, .-Reset_Handler
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
.section .vectors,"a",%progbits
.global __gVectors
__gVectors:
.word _sp /* Top of Stack */
.word Reset_Handler /* Reset Handler */
.word NMI_Handler /* NMI Handler */
.word HardFault_Handler /* Hard Fault Handler */
.word MemManage_Handler /* MPU Fault Handler */
.word BusFault_Handler /* Bus Fault Handler */
.word UsageFault_Handler /* Usage Fault Handler */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word SVC_Handler /* SVCall Handler */
.word DebugMon_Handler /* Debug Monitor Handler */
.word 0 /* Reserved */
.word PendSV_Handler /* PendSV Handler */
.word SysTick_Handler /* SysTick Handler */
/* External interrupts handler */
.word WWDGT_IRQHandler /* Vector Number 16,Window Watchdog Timer */
.word VAVD_LVD_VOVD_IRQHandler /* Vector Number 17,VAVD/LVD/VOVD through EXTI Line detect */
.word TAMPER_STAMP_LXTAL_IRQHandler /* Vector Number 18,RTC Tamper and TimeStamp through EXTI Line detect, LXTAL clock security system interrupt */
.word RTC_WKUP_IRQHandler /* Vector Number 19,RTC Wakeup from EXTI interrupt */
.word FMC_IRQHandler /* Vector Number 20,FMC global interrupt */
.word RCU_IRQHandler /* Vector Number 21,RCU global interrupt */
.word EXTI0_IRQHandler /* Vector Number 22,EXTI Line 0 */
.word EXTI1_IRQHandler /* Vector Number 23,EXTI Line 1 */
.word EXTI2_IRQHandler /* Vector Number 24,EXTI Line 2 */
.word EXTI3_IRQHandler /* Vector Number 25,EXTI Line 3 */
.word EXTI4_IRQHandler /* Vector Number 26,EXTI Line 4 */
.word DMA0_Channel0_IRQHandler /* Vector Number 27,DMA0 Channel 0 */
.word DMA0_Channel1_IRQHandler /* Vector Number 28,DMA0 Channel 1 */
.word DMA0_Channel2_IRQHandler /* Vector Number 29,DMA0 Channel 2 */
.word DMA0_Channel3_IRQHandler /* Vector Number 30,DMA0 Channel 3 */
.word DMA0_Channel4_IRQHandler /* Vector Number 31,DMA0 Channel 4 */
.word DMA0_Channel5_IRQHandler /* Vector Number 32,DMA0 Channel 5 */
.word DMA0_Channel6_IRQHandler /* Vector Number 33,DMA0 Channel 6 */
.word ADC0_1_IRQHandler /* Vector Number 34,ADC0 and ADC1 interrupt */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word EXTI5_9_IRQHandler /* Vector Number 39,EXTI5 to EXTI9 */
.word TIMER0_BRK_IRQHandler /* Vector Number 40,TIMER0 Break */
.word TIMER0_UP_IRQHandler /* Vector Number 41,TIMER0 Update */
.word TIMER0_TRG_CMT_IRQHandler /* Vector Number 42,TIMER0 Trigger and Commutation */
.word TIMER0_Channel_IRQHandler /* Vector Number 43,TIMER0 Capture Compare */
.word TIMER1_IRQHandler /* Vector Number 44,TIMER1 */
.word TIMER2_IRQHandler /* Vector Number 45,TIMER2 */
.word TIMER3_IRQHandler /* Vector Number 46,TIMER3 */
.word I2C0_EV_IRQHandler /* Vector Number 47,I2C0 Event */
.word I2C0_ER_IRQHandler /* Vector Number 48,I2C0 Error */
.word I2C1_EV_IRQHandler /* Vector Number 49,I2C1 Event */
.word I2C1_ER_IRQHandler /* Vector Number 50,I2C1 Error */
.word SPI0_IRQHandler /* Vector Number 51,SPI0 */
.word SPI1_IRQHandler /* Vector Number 52,SPI1 */
.word USART0_IRQHandler /* Vector Number 53,USART0 global and wakeup */
.word USART1_IRQHandler /* Vector Number 54,USART1 global and wakeup */
.word USART2_IRQHandler /* Vector Number 55,USART2 global and wakeup */
.word EXTI10_15_IRQHandler /* Vector Number 56,EXTI10 to EXTI15 */
.word RTC_Alarm_IRQHandler /* Vector Number 57,RTC Alarm */
.word 0 /* Reserved */
.word TIMER7_BRK_IRQHandler /* Vector Number 59,TIMER7 Break */
.word TIMER7_UP_IRQHandler /* Vector Number 60,TIMER7 Update */
.word TIMER7_TRG_CMT_IRQHandler /* Vector Number 61,TIMER7 Trigger and Commutation */
.word TIMER7_Channel_IRQHandler /* Vector Number 62,TIMER7 Channel Capture Compare */
.word DMA0_Channel7_IRQHandler /* Vector Number 63,DMA0 Channel 7 */
.word EXMC_IRQHandler /* Vector Number 64,EXMC */
.word 0 /* Reserved */
.word TIMER4_IRQHandler /* Vector Number 66,TIMER4 */
.word SPI2_IRQHandler /* Vector Number 67,SPI2 */
.word UART3_IRQHandler /* Vector Number 68,UART3 */
.word UART4_IRQHandler /* Vector Number 69,UART4 */
.word TIMER5_DAC_UDR_IRQHandler /* Vector Number 70,TIMER5 global interrupt and DAC1/DAC0 underrun error */
.word TIMER6_IRQHandler /* Vector Number 71,TIMER6 */
.word DMA1_Channel0_IRQHandler /* Vector Number 72,DMA1 Channel0 */
.word DMA1_Channel1_IRQHandler /* Vector Number 73,DMA1 Channel1 */
.word DMA1_Channel2_IRQHandler /* Vector Number 74,DMA1 Channel2 */
.word DMA1_Channel3_IRQHandler /* Vector Number 75,DMA1 Channel3 */
.word DMA1_Channel4_IRQHandler /* Vector Number 76,DMA1 Channel4 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word DMA1_Channel5_IRQHandler /* Vector Number 84,DMA1 Channel5 */
.word DMA1_Channel6_IRQHandler /* Vector Number 85,DMA1 Channel6 */
.word DMA1_Channel7_IRQHandler /* Vector Number 86,DMA1 Channel7 */
.word USART5_IRQHandler /* Vector Number 87,USART5 global and wakeup */
.word I2C2_EV_IRQHandler /* Vector Number 88,I2C2 Event */
.word I2C2_ER_IRQHandler /* Vector Number 89,I2C2 Error */
.word USBHS0_EP1_OUT_IRQHandler /* Vector Number 90,USBHS0 Endpoint 1 Out */
.word USBHS0_EP1_IN_IRQHandler /* Vector Number 91,USBHS0 Endpoint 1 in */
.word USBHS0_WKUP_IRQHandler /* Vector Number 92,USBHS0 Wakeup through EXTI Line */
.word USBHS0_IRQHandler /* Vector Number 93,USBHS0 */
.word 0 /* Vector Number 94,Reserved */
.word 0 /* Vector Number 95,Reserved */
.word TRNG_IRQHandler /* Vector Number 96,TRNG */
.word FPU_IRQHandler /* Vector Number 97,FPU */
.word UART6_IRQHandler /* Vector Number 98,UART6 */
.word UART7_IRQHandler /* Vector Number 99,UART7 */
.word SPI3_IRQHandler /* Vector Number 100,SPI3 */
.word SPI4_IRQHandler /* Vector Number 101,SPI4 */
.word SPI5_IRQHandler /* Vector Number 102,SPI5 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word OSPI0_IRQHandler /* Vector Number 108,OSPI0 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word I2C3_EV_IRQHandler /* Vector Number 111,I2C3 Event */
.word I2C3_ER_IRQHandler /* Vector Number 112,I2C3 Error */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word DMAMUX_OVR_IRQHandler /* Vector Number 118,DMAMUX Overrun interrupt */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word HPDF_INT0_IRQHandler /* Vector Number 126,HPDF global interrupt 0 */
.word HPDF_INT1_IRQHandler /* Vector Number 127,HPDF global interrupt 1 */
.word HPDF_INT2_IRQHandler /* Vector Number 128,HPDF global interrupt 2 */
.word HPDF_INT3_IRQHandler /* Vector Number 129,HPDF global interrupt 3 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word TIMER14_IRQHandler /* Vector Number 132,TIMER14 */
.word TIMER15_IRQHandler /* Vector Number 133,TIMER15 */
.word TIMER16_IRQHandler /* Vector Number 134,TIMER16 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word MDMA_IRQHandler /* Vector Number 138,MDMA */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word ADC2_IRQHandler /* Vector Number 143,ADC2 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word CMP0_1_IRQHandler /* Vector Number 153,CMP0 and CMP1 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word CTC_IRQHandler /* Vector Number 160,Clock Recovery System */
.word RAMECCMU_IRQHandler /* Vector Number 161,RAMECCMU */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word OSPI1_IRQHandler /* Vector Number 166,OSPI1 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word FAC_IRQHandler /* Vector Number 169,FAC */
.word TMU_IRQHandler /* Vector Number 170,TMU */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word TIMER22_IRQHandler /* Vector Number 177,TIMER22 */
.word TIMER23_IRQHandler /* Vector Number 178,TIMER23 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word TIMER40_IRQHandler /* Vector Number 181,TIMER40 */
.word TIMER41_IRQHandler /* Vector Number 182,TIMER41 */
.word TIMER42_IRQHandler /* Vector Number 183,TIMER42 */
.word TIMER43_IRQHandler /* Vector Number 184,TIMER43 */
.word TIMER44_IRQHandler /* Vector Number 185,TIMER44 */
.word TIMER50_IRQHandler /* Vector Number 186,TIMER50 */
.word TIMER51_IRQHandler /* Vector Number 187,TIMER51 */
.word USBHS1_EP1_OUT_IRQHandler /* Vector Number 188,USBHS1 endpoint 1 out */
.word USBHS1_EP1_IN_IRQHandler /* Vector Number 189,USBHS1 endpoint 1 in */
.word USBHS1_WKUP_IRQHandler /* Vector Number 190,USBHS1 wakeup */
.word USBHS1_IRQHandler /* Vector Number 191,USBHS1 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word CAN0_WKUP_IRQHandler /* Vector Number 195,CAN0 wakeup */
.word CAN0_Message_IRQHandler /* Vector Number 196,CAN0 interrupt for message buffer */
.word CAN0_Busoff_IRQHandler /* Vector Number 197,CAN0 interrupt for Bus off / Bus off done */
.word CAN0_Error_IRQHandler /* Vector Number 198,CAN0 interrupt for Error */
.word CAN0_FastError_IRQHandler /* Vector Number 199,CAN0 interrupt for Error in fast transmission */
.word CAN0_TEC_IRQHandler /* Vector Number 200,CAN0 interrupt for Transmit warning */
.word CAN0_REC_IRQHandler /* Vector Number 201,CAN0 interrupt for Receive warning */
.word CAN1_WKUP_IRQHandler /* Vector Number 202,CAN1 wakeup */
.word CAN1_Message_IRQHandler /* Vector Number 203,CAN1 interrupt for message buffer */
.word CAN1_Busoff_IRQHandler /* Vector Number 204,CAN1 interrupt for Bus off / Bus off done */
.word CAN1_Error_IRQHandler /* Vector Number 205,CAN1 interrupt for Error */
.word CAN1_FastError_IRQHandler /* Vector Number 206,CAN1 interrupt for Error in fast transmission */
.word CAN1_TEC_IRQHandler /* Vector Number 207,CAN1 interrupt for Transmit warning */
.word CAN1_REC_IRQHandler /* Vector Number 208,CAN1 interrupt for Receive warning */
.word CAN2_WKUP_IRQHandler /* Vector Number 209,CAN2 wakeup */
.word CAN2_Message_IRQHandler /* Vector Number 210,CAN2 interrupt for message buffer */
.word CAN2_Busoff_IRQHandler /* Vector Number 211,CAN2 interrupt for Bus off / Bus off done */
.word CAN2_Error_IRQHandler /* Vector Number 212,CAN2 interrupt for Error */
.word CAN2_FastError_IRQHandler /* Vector Number 213,CAN2 interrupt for Error in fast transmission */
.word CAN2_TEC_IRQHandler /* Vector Number 214,CAN2 interrupt for Transmit warning */
.word CAN2_REC_IRQHandler /* Vector Number 215,CAN2 interrupt for Receive warning */
.word EFUSE_IRQHandler /* Vector Number 216,EFUSE */
.word I2C0_WKUP_IRQHandler /* Vector Number 217,I2C0 wakeup */
.word I2C1_WKUP_IRQHandler /* Vector Number 218,I2C1 wakeup */
.word I2C2_WKUP_IRQHandler /* Vector Number 219,I2C2 wakeup */
.word I2C3_WKUP_IRQHandler /* Vector Number 220,I2C3 wakeup */
.word LPDTS_IRQHandler /* Vector Number 221,LPDTS */
.word LPDTS_WKUP_IRQHandler /* Vector Number 222,LPDTS wakeup */
.word TIMER0_DEC_IRQHandler /* Vector Number 223,TIMER0 DEC */
.word TIMER7_DEC_IRQHandler /* Vector Number 224,TIMER7 DEC */
.word TIMER1_DEC_IRQHandler /* Vector Number 225,TIMER1 DEC */
.word TIMER2_DEC_IRQHandler /* Vector Number 226,TIMER2 DEC */
.word TIMER3_DEC_IRQHandler /* Vector Number 227,TIMER3 DEC */
.word TIMER4_DEC_IRQHandler /* Vector Number 228,TIMER4 DEC */
.word TIMER22_DEC_IRQHandler /* Vector Number 229,TIMER22 DEC */
.word TIMER23_DEC_IRQHandler /* Vector Number 230,TIMER23 DEC */
.word 0 /* Reserved */
.word 0 /* Reserved */
.size __gVectors, . - __gVectors
.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 WWDGT_IRQHandler
.thumb_set WWDGT_IRQHandler,Default_Handler
.weak VAVD_LVD_VOVD_IRQHandler
.thumb_set VAVD_LVD_VOVD_IRQHandler,Default_Handler
.weak TAMPER_STAMP_LXTAL_IRQHandler
.thumb_set TAMPER_STAMP_LXTAL_IRQHandler,Default_Handler
.weak RTC_WKUP_IRQHandler
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
.weak FMC_IRQHandler
.thumb_set FMC_IRQHandler,Default_Handler
.weak RCU_IRQHandler
.thumb_set RCU_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 DMA0_Channel0_IRQHandler
.thumb_set DMA0_Channel0_IRQHandler,Default_Handler
.weak DMA0_Channel1_IRQHandler
.thumb_set DMA0_Channel1_IRQHandler,Default_Handler
.weak DMA0_Channel2_IRQHandler
.thumb_set DMA0_Channel2_IRQHandler,Default_Handler
.weak DMA0_Channel3_IRQHandler
.thumb_set DMA0_Channel3_IRQHandler,Default_Handler
.weak DMA0_Channel4_IRQHandler
.thumb_set DMA0_Channel4_IRQHandler,Default_Handler
.weak DMA0_Channel5_IRQHandler
.thumb_set DMA0_Channel5_IRQHandler,Default_Handler
.weak DMA0_Channel6_IRQHandler
.thumb_set DMA0_Channel6_IRQHandler,Default_Handler
.weak ADC0_1_IRQHandler
.thumb_set ADC0_1_IRQHandler,Default_Handler
.weak EXTI5_9_IRQHandler
.thumb_set EXTI5_9_IRQHandler,Default_Handler
.weak TIMER0_BRK_IRQHandler
.thumb_set TIMER0_BRK_IRQHandler,Default_Handler
.weak TIMER0_UP_IRQHandler
.thumb_set TIMER0_UP_IRQHandler,Default_Handler
.weak TIMER0_TRG_CMT_IRQHandler
.thumb_set TIMER0_TRG_CMT_IRQHandler,Default_Handler
.weak TIMER0_Channel_IRQHandler
.thumb_set TIMER0_Channel_IRQHandler,Default_Handler
.weak TIMER1_IRQHandler
.thumb_set TIMER1_IRQHandler,Default_Handler
.weak TIMER2_IRQHandler
.thumb_set TIMER2_IRQHandler,Default_Handler
.weak TIMER3_IRQHandler
.thumb_set TIMER3_IRQHandler,Default_Handler
.weak I2C0_EV_IRQHandler
.thumb_set I2C0_EV_IRQHandler,Default_Handler
.weak I2C0_ER_IRQHandler
.thumb_set I2C0_ER_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 SPI0_IRQHandler
.thumb_set SPI0_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak USART0_IRQHandler
.thumb_set USART0_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak EXTI10_15_IRQHandler
.thumb_set EXTI10_15_IRQHandler,Default_Handler
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak TIMER7_BRK_IRQHandler
.thumb_set TIMER7_BRK_IRQHandler,Default_Handler
.weak TIMER7_UP_IRQHandler
.thumb_set TIMER7_UP_IRQHandler,Default_Handler
.weak TIMER7_TRG_CMT_IRQHandler
.thumb_set TIMER7_TRG_CMT_IRQHandler,Default_Handler
.weak TIMER7_Channel_IRQHandler
.thumb_set TIMER7_Channel_IRQHandler,Default_Handler
.weak DMA0_Channel7_IRQHandler
.thumb_set DMA0_Channel7_IRQHandler,Default_Handler
.weak EXMC_IRQHandler
.thumb_set EXMC_IRQHandler,Default_Handler
.weak TIMER4_IRQHandler
.thumb_set TIMER4_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak UART3_IRQHandler
.thumb_set UART3_IRQHandler,Default_Handler
.weak UART4_IRQHandler
.thumb_set UART4_IRQHandler,Default_Handler
.weak TIMER5_DAC_UDR_IRQHandler
.thumb_set TIMER5_DAC_UDR_IRQHandler,Default_Handler
.weak TIMER6_IRQHandler
.thumb_set TIMER6_IRQHandler,Default_Handler
.weak DMA1_Channel0_IRQHandler
.thumb_set DMA1_Channel0_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 USART5_IRQHandler
.thumb_set USART5_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 USBHS0_EP1_OUT_IRQHandler
.thumb_set USBHS0_EP1_OUT_IRQHandler,Default_Handler
.weak USBHS0_EP1_IN_IRQHandler
.thumb_set USBHS0_EP1_IN_IRQHandler,Default_Handler
.weak USBHS0_WKUP_IRQHandler
.thumb_set USBHS0_WKUP_IRQHandler,Default_Handler
.weak USBHS0_IRQHandler
.thumb_set USBHS0_IRQHandler,Default_Handler
.weak TRNG_IRQHandler
.thumb_set TRNG_IRQHandler,Default_Handler
.weak FPU_IRQHandler
.thumb_set FPU_IRQHandler,Default_Handler
.weak UART6_IRQHandler
.thumb_set UART6_IRQHandler,Default_Handler
.weak UART7_IRQHandler
.thumb_set UART7_IRQHandler,Default_Handler
.weak SPI3_IRQHandler
.thumb_set SPI3_IRQHandler,Default_Handler
.weak SPI4_IRQHandler
.thumb_set SPI4_IRQHandler,Default_Handler
.weak SPI5_IRQHandler
.thumb_set SPI5_IRQHandler,Default_Handler
.weak OSPI0_IRQHandler
.thumb_set OSPI0_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 DMAMUX_OVR_IRQHandler
.thumb_set DMAMUX_OVR_IRQHandler,Default_Handler
.weak HPDF_INT0_IRQHandler
.thumb_set HPDF_INT0_IRQHandler,Default_Handler
.weak HPDF_INT1_IRQHandler
.thumb_set HPDF_INT1_IRQHandler,Default_Handler
.weak HPDF_INT2_IRQHandler
.thumb_set HPDF_INT2_IRQHandler,Default_Handler
.weak HPDF_INT3_IRQHandler
.thumb_set HPDF_INT3_IRQHandler,Default_Handler
.weak TIMER14_IRQHandler
.thumb_set TIMER14_IRQHandler,Default_Handler
.weak TIMER15_IRQHandler
.thumb_set TIMER15_IRQHandler,Default_Handler
.weak TIMER16_IRQHandler
.thumb_set TIMER16_IRQHandler,Default_Handler
.weak MDMA_IRQHandler
.thumb_set MDMA_IRQHandler,Default_Handler
.weak ADC2_IRQHandler
.thumb_set ADC2_IRQHandler,Default_Handler
.weak CMP0_1_IRQHandler
.thumb_set CMP0_1_IRQHandler,Default_Handler
.weak CTC_IRQHandler
.thumb_set CTC_IRQHandler,Default_Handler
.weak RAMECCMU_IRQHandler
.thumb_set RAMECCMU_IRQHandler,Default_Handler
.weak OSPI1_IRQHandler
.thumb_set OSPI1_IRQHandler,Default_Handler
.weak FAC_IRQHandler
.thumb_set FAC_IRQHandler,Default_Handler
.weak TMU_IRQHandler
.thumb_set TMU_IRQHandler,Default_Handler
.weak TIMER22_IRQHandler
.thumb_set TIMER22_IRQHandler,Default_Handler
.weak TIMER23_IRQHandler
.thumb_set TIMER23_IRQHandler,Default_Handler
.weak TIMER40_IRQHandler
.thumb_set TIMER40_IRQHandler,Default_Handler
.weak TIMER41_IRQHandler
.thumb_set TIMER41_IRQHandler,Default_Handler
.weak TIMER42_IRQHandler
.thumb_set TIMER42_IRQHandler,Default_Handler
.weak TIMER43_IRQHandler
.thumb_set TIMER43_IRQHandler,Default_Handler
.weak TIMER44_IRQHandler
.thumb_set TIMER44_IRQHandler,Default_Handler
.weak TIMER50_IRQHandler
.thumb_set TIMER50_IRQHandler,Default_Handler
.weak TIMER51_IRQHandler
.thumb_set TIMER51_IRQHandler,Default_Handler
.weak USBHS1_EP1_OUT_IRQHandler
.thumb_set USBHS1_EP1_OUT_IRQHandler,Default_Handler
.weak USBHS1_EP1_IN_IRQHandler
.thumb_set USBHS1_EP1_IN_IRQHandler,Default_Handler
.weak USBHS1_WKUP_IRQHandler
.thumb_set USBHS1_WKUP_IRQHandler,Default_Handler
.weak USBHS1_IRQHandler
.thumb_set USBHS1_IRQHandler,Default_Handler
.weak CAN0_WKUP_IRQHandler
.thumb_set CAN0_WKUP_IRQHandler,Default_Handler
.weak CAN0_Message_IRQHandler
.thumb_set CAN0_Message_IRQHandler,Default_Handler
.weak CAN0_Busoff_IRQHandler
.thumb_set CAN0_Busoff_IRQHandler,Default_Handler
.weak CAN0_Error_IRQHandler
.thumb_set CAN0_Error_IRQHandler,Default_Handler
.weak CAN0_FastError_IRQHandler
.thumb_set CAN0_FastError_IRQHandler,Default_Handler
.weak CAN0_TEC_IRQHandler
.thumb_set CAN0_TEC_IRQHandler,Default_Handler
.weak CAN0_REC_IRQHandler
.thumb_set CAN0_REC_IRQHandler,Default_Handler
.weak CAN1_WKUP_IRQHandler
.thumb_set CAN1_WKUP_IRQHandler,Default_Handler
.weak CAN1_Message_IRQHandler
.thumb_set CAN1_Message_IRQHandler,Default_Handler
.weak CAN1_Busoff_IRQHandler
.thumb_set CAN1_Busoff_IRQHandler,Default_Handler
.weak CAN1_Error_IRQHandler
.thumb_set CAN1_Error_IRQHandler,Default_Handler
.weak CAN1_FastError_IRQHandler
.thumb_set CAN1_FastError_IRQHandler,Default_Handler
.weak CAN1_TEC_IRQHandler
.thumb_set CAN1_TEC_IRQHandler,Default_Handler
.weak CAN1_REC_IRQHandler
.thumb_set CAN1_REC_IRQHandler,Default_Handler
.weak CAN2_WKUP_IRQHandler
.thumb_set CAN2_WKUP_IRQHandler,Default_Handler
.weak CAN2_Message_IRQHandler
.thumb_set CAN2_Message_IRQHandler,Default_Handler
.weak CAN2_Busoff_IRQHandler
.thumb_set CAN2_Busoff_IRQHandler,Default_Handler
.weak CAN2_Error_IRQHandler
.thumb_set CAN2_Error_IRQHandler,Default_Handler
.weak CAN2_FastError_IRQHandler
.thumb_set CAN2_FastError_IRQHandler,Default_Handler
.weak CAN2_TEC_IRQHandler
.thumb_set CAN2_TEC_IRQHandler,Default_Handler
.weak CAN2_REC_IRQHandler
.thumb_set CAN2_REC_IRQHandler,Default_Handler
.weak EFUSE_IRQHandler
.thumb_set EFUSE_IRQHandler,Default_Handler
.weak I2C0_WKUP_IRQHandler
.thumb_set I2C0_WKUP_IRQHandler,Default_Handler
.weak I2C1_WKUP_IRQHandler
.thumb_set I2C1_WKUP_IRQHandler,Default_Handler
.weak I2C2_WKUP_IRQHandler
.thumb_set I2C2_WKUP_IRQHandler,Default_Handler
.weak I2C3_WKUP_IRQHandler
.thumb_set I2C3_WKUP_IRQHandler,Default_Handler
.weak LPDTS_IRQHandler
.thumb_set LPDTS_IRQHandler,Default_Handler
.weak LPDTS_WKUP_IRQHandler
.thumb_set LPDTS_WKUP_IRQHandler,Default_Handler
.weak TIMER0_DEC_IRQHandler
.thumb_set TIMER0_DEC_IRQHandler,Default_Handler
.weak TIMER7_DEC_IRQHandler
.thumb_set TIMER7_DEC_IRQHandler,Default_Handler
.weak TIMER1_DEC_IRQHandler
.thumb_set TIMER1_DEC_IRQHandler,Default_Handler
.weak TIMER2_DEC_IRQHandler
.thumb_set TIMER2_DEC_IRQHandler,Default_Handler
.weak TIMER3_DEC_IRQHandler
.thumb_set TIMER3_DEC_IRQHandler,Default_Handler
.weak TIMER4_DEC_IRQHandler
.thumb_set TIMER4_DEC_IRQHandler,Default_Handler
.weak TIMER22_DEC_IRQHandler
.thumb_set TIMER22_DEC_IRQHandler,Default_Handler
.weak TIMER23_DEC_IRQHandler
.thumb_set TIMER23_DEC_IRQHandler,Default_Handler

61
828ECO/libraries/CMSIS/GD/GD32H75E/Source/gd32h75e_err_report.c

@ -0,0 +1,61 @@
/*!
\file gd32h75e_report_err.c
\brief Reporting Error driver
\version 2025-01-24, V1.1.0, firmware for GD32H75E
*/
/*
Copyright (c) 2025, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#include "gd32h75e_err_report.h"
/* initialize the error report buffer and index */
err_report_struct err_report_buffer[ERR_REPORT_BUFFER_SIZE];
uint8_t err_report_buff_index = 0x00U;
/*!
\brief reporting error in debug mode
\param[in] moduleid: module ID where the error occurred
\param[in] apiid: API ID associated with the error
\param[in] errid: error ID indicating the specific error type
\param[out] err_report_buffer: stores the id of the error type
\retval none
*/
void fw_debug_report_err(uint16_t moduleid, uint16_t apiid, uint8_t errid)
{
err_report_struct *debug_report_err_buffer;
if(err_report_buff_index < ERR_REPORT_BUFFER_SIZE) {
debug_report_err_buffer = &err_report_buffer[err_report_buff_index++];
debug_report_err_buffer->moduleid = moduleid;
debug_report_err_buffer->apiid = apiid;
debug_report_err_buffer->errid = errid;
} else {
/* illegal parameters */
}
}

877
828ECO/libraries/CMSIS/GD/GD32H75E/Source/system_gd32h75e.c

@ -0,0 +1,877 @@
/*!
\file system_gd32h75e.c
\brief CMSIS Cortex-M7 Device Peripheral Access Layer Source File for
gd32h75e Device Series
*/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
* Copyright (c) 2025, GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
#include "gd32h75e.h"
/* system frequency define */
#define __IRC64M (IRC64M_VALUE) /* internal 64 MHz RC oscillator frequency */
#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */
#define __LPIRC4M (LPIRC4M_VALUE) /* low power internal 4 MHz RC oscillator frequency */
#define __SYS_OSC_CLK (__IRC64M) /* main oscillator frequency */
#define VECT_TAB_OFFSET (uint32_t)0x00 /* vector table base offset */
#define RCU_APB4EN_SYSCFG (uint32_t)0x01 /* enable SYSCFG clk */
/* select a system clock by uncommenting the following line */
/* use IRC64M */
//#define __SYSTEM_CLOCK_IRC64M (__IRC64M)
//#define __SYSTEM_CLOCK_480M_PLL0_IRC64M (uint32_t)(480000000)
//#define __SYSTEM_CLOCK_600M_PLL0_IRC64M (uint32_t)(600000000)
/* use LPIRC4M */
//#define __SYSTEM_CLOCK_LPIRC4M (__LPIRC4M)
/* use HXTAL(CK_HXTAL = 25M) */
//#define __SYSTEM_CLOCK_HXTAL (__HXTAL)
//#define __SYSTEM_CLOCK_200M_PLL0_HXTAL (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_400M_PLL0_HXTAL (uint32_t)(400000000)
//#define __SYSTEM_CLOCK_480M_PLL0_HXTAL (uint32_t)(480000000)
#define __SYSTEM_CLOCK_600M_PLL0_HXTAL (uint32_t)(600000000)
/*
Note: the power mode need to match the mcu selection and external power supply circuit.
according to the selected mcu and external power supply circuit to uncomment
the following macro SEL_PMU_SMPS_MODE.
*/
//#define SEL_PMU_SMPS_MODE PMU_LDO_SUPPLY
//#define SEL_PMU_SMPS_MODE PMU_DIRECT_SMPS_SUPPLY
//#define SEL_PMU_SMPS_MODE PMU_BYPASS
#define SEL_IRC64MDIV 0x00U
#define SEL_HXTAL 0x01U
#define SEL_LPIRC4M 0x02U
#define SEL_PLL0P 0x03U
#define PLL0PSC_REG_OFFSET 0U
#define PLL0N_REG_OFFSET 6U
#define PLL0P_REG_OFFSET 16U
#define PLL0Q_REG_OFFSET 0U
#define PLL0R_REG_OFFSET 24U
/* set the system clock frequency and declare the system clock configuration function */
#ifdef __SYSTEM_CLOCK_IRC64M
uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC64M;
static void system_clock_64m_irc64m(void);
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M)
#define PLL0PSC 16U
#define PLL0N (120U - 1U)
#define PLL0P (1U - 1U)
#define PLL0Q (2U - 1U)
#define PLL0R (2U - 1U)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_480M_PLL0_IRC64M;
static void system_clock_480m_irc64m(void);
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M)
#define PLL0PSC 16U
#define PLL0N (150U - 1U)
#define PLL0P (1U - 1U)
#define PLL0Q (2U - 1U)
#define PLL0R (2U - 1U)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_IRC64M;
static void system_clock_600m_irc64m(void);
#elif defined (__SYSTEM_CLOCK_LPIRC4M)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_LPIRC4M;
static void system_clock_4m_lpirc4m(void);
#elif defined (__SYSTEM_CLOCK_HXTAL)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL;
static void system_clock_hxtal(void);
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL)
#define PLL0PSC 5U
#define PLL0N (40U - 1U)
#define PLL0P (1U - 1U)
#define PLL0Q (2U - 1U)
#define PLL0R (2U - 1U)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL0_HXTAL;
static void system_clock_200m_hxtal(void);
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL)
#define PLL0PSC 5U
#define PLL0N (80U - 1U)
#define PLL0P (1U - 1U)
#define PLL0Q (2U - 1U)
#define PLL0R (2U - 1U)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_400M_PLL0_HXTAL;
static void system_clock_400m_hxtal(void);
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL)
#define PLL0PSC 5U
#define PLL0N (96U - 1U)
#define PLL0P (1U - 1U)
#define PLL0Q (2U - 1U)
#define PLL0R (2U - 1U)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_480M_PLL0_HXTAL;
static void system_clock_480m_hxtal(void);
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL)
#define PLL0PSC 5U
#define PLL0N (120U - 1U)
#define PLL0P (1U - 1U)
#define PLL0Q (2U - 1U)
#define PLL0R (2U - 1U)
uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_HXTAL;
static void system_clock_600m_hxtal(void);
#endif /* __SYSTEM_CLOCK_IRC64M */
/* configure the system clock */
static void system_clock_config(void);
/*!
\brief setup the microcontroller system, initialize the system
\param[in] none
\param[out] none
\retval none
*/
void SystemInit(void)
{
/* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1U)
/* set CP10 and CP11 Full Access */
SCB->CPACR |= (uint32_t)((0x03U << 10U * 2U) | (0x03U << 11U * 2U));
#endif
/* enable IRC64M */
RCU_CTL |= RCU_CTL_IRC64MEN;
while(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
}
/* no TCM wait state */
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
SYSCFG_SRAMCFG1 &= ~SYSCFG_SRAMCFG1_TCM_WAITSTATE;
RCU_CFG0 &= ~RCU_CFG0_SCS;
/* reset RCU */
/* reset HXTALEN, CKMEN, PLL0EN, PLL1EN, PLL2EN, PLLUSB0 and PLLUSB1 bits */
RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLL0EN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_HXTALBPS);
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_PLLUSBHS0EN | RCU_ADDCTL1_PLLUSBHS1EN | RCU_ADDCTL1_LPIRC4MEN);
/* reset CFG0, CFG1, CFG2, CFG3 registers */
RCU_CFG0 &= ~(RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_APB3PSC | RCU_CFG0_APB4PSC | RCU_CFG0_AHBPSC |
RCU_CFG0_I2C0SEL | RCU_CFG0_SCS | RCU_CFG0_RTCDIV);
RCU_CFG1 &= ~(RCU_CFG1_HPDFSEL | RCU_CFG1_TIMERSEL | RCU_CFG1_PERSEL |
RCU_CFG1_USART0SEL | RCU_CFG1_USART1SEL | RCU_CFG1_USART2SEL | RCU_CFG1_USART5SEL | RCU_CFG1_PLL2RDIV);
RCU_CFG2 &= ~(RCU_CFG2_HPDFASEL | RCU_CFG2_CKOUT0SEL | RCU_CFG2_CKOUT1SEL | RCU_CFG2_CKOUT0DIV | RCU_CFG2_CKOUT1DIV);
RCU_CFG3 &= ~(RCU_CFG3_ADC01SEL | RCU_CFG3_ADC2SEL
| RCU_CFG3_I2C3SEL | RCU_CFG3_I2C2SEL | RCU_CFG3_I2C1SEL);
RCU_CFG4 &= ~(RCU_CFG4_EXMCSEL);
RCU_CFG5 &= ~(RCU_CFG5_SPI0SEL | RCU_CFG5_SPI1SEL | RCU_CFG5_SPI2SEL |
RCU_CFG5_SPI3SEL | RCU_CFG5_SPI4SEL | RCU_CFG5_SPI5SEL);
/* disable all interrupts */
RCU_INT = 0x14FF0000U;
RCU_ADDINT = 0x00700000U;
/* reset all PLL0 parameter */
RCU_PLL0 = 0x01002020U;
RCU_PLL1 = 0x01012020U;
RCU_PLL2 = 0x01012020U;
RCU_PLLALL = 0x00000000U;
RCU_PLLADDCTL = 0x00010101U;
RCU_PLLUSBCFG = 0x00000000U;
RCU_PLL0FRA = 0x00000000U;
RCU_PLL1FRA = 0x00000000U;
RCU_PLL2FRA = 0x00000000U;
#if defined (SEL_PMU_SMPS_MODE)
/* power supply config */
pmu_smps_ldo_supply_config(SEL_PMU_SMPS_MODE);
#endif
/* configure system clock */
system_clock_config();
#ifdef VECT_TAB_SRAM
nvic_vector_table_set(NVIC_VECTTAB_RAM, VECT_TAB_OFFSET);
#else
nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET);
#endif
}
/*!
\brief configure the system clock
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_config(void)
{
#ifdef __SYSTEM_CLOCK_IRC64M
system_clock_64m_irc64m();
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M)
system_clock_480m_irc64m();
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M)
system_clock_600m_irc64m();
#elif defined (__SYSTEM_CLOCK_LPIRC4M)
system_clock_4m_lpirc4m();
#elif defined (__SYSTEM_CLOCK_HXTAL)
system_clock_hxtal();
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL)
system_clock_200m_hxtal();
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL)
system_clock_400m_hxtal();
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL)
system_clock_480m_hxtal();
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL)
system_clock_600m_hxtal();
#endif /* __SYSTEM_CLOCK_IRC64M */
}
#ifdef __SYSTEM_CLOCK_IRC64M
/*!
\brief configure the system clock to 64M by IRC64M
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_64m_irc64m(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable IRC64M */
RCU_CTL |= RCU_CTL_IRC64MEN;
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB);
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
while(1) {
}
}
/* AHB = SYSCLK / 1 */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB4 = AHB / 1 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1;
/* APB3 = AHB / 1 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 1 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
/* configure IRC64M div */
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV);
RCU_ADDCTL1 |= RCU_IRC64M_DIV1;
/* select IRC64M as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_IRC64MDIV;
/* wait until IRC64M is selected as system clock */
while(RCU_SCSS_IRC64MDIV != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M)
/*!
\brief configure the system clock to 480M by PLL0 which selects IRC64M as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_480m_irc64m(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable IRC64M */
RCU_CTL |= RCU_CTL_IRC64MEN;
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB);
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
while(1) {
}
}
/* insert TCM wait state at 480MHz */
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
/* IRC64M is already stable */
/* AHB = SYSCLK / 2 */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
/* APB4 = AHB / 2 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
/* APB3 = AHB / 2 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
/* PLL0 select IRC64MDIV, config IRC64MDIV as IRC64M, PLL0 input and output range */
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV);
RCU_ADDCTL1 |= RCU_IRC64M_DIV1;
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
RCU_PLLALL |= (RCU_PLLSRC_IRC64MDIV | RCU_PLL0RNG_4M_8M);
/* PLL0P = IRC64MDIV / 16 * 120 / 1 = 480 MHz */
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
/* enable PLL0P, PLL0Q, PLL0R */
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
/* enable PLL0 */
RCU_CTL |= RCU_CTL_PLL0EN;
/* wait until PLL0 is stable */
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
}
/* select PLL0 as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
/* wait until PLL0 is selected as system clock */
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M)
/*!
\brief configure the system clock to 600M by PLL0 which selects IRC64M as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_600m_irc64m(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable IRC64M */
RCU_CTL |= RCU_CTL_IRC64MEN;
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB);
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
while(1) {
}
}
/* insert TCM wait state at 600MHz */
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
/* IRC64M is already stable */
/* AHB = SYSCLK / 2 */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
/* APB4 = AHB / 2 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
/* APB3 = AHB / 2 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
/* PLL0 select IRC64MDIV, config IRC64MDIV as IRC64M, PLL0 input and output range */
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV);
RCU_ADDCTL1 |= RCU_IRC64M_DIV1;
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
RCU_PLLALL |= (RCU_PLLSRC_IRC64MDIV | RCU_PLL0RNG_4M_8M);
/* PLL0P = IRC64MDIV / 16 * 150 / 1 = 600 MHz */
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
/* enable PLL0P, PLL0Q, PLL0R */
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
/* enable PLL0 */
RCU_CTL |= RCU_CTL_PLL0EN;
/* wait until PLL0 is stable */
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
}
/* select PLL0 as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
/* wait until PLL0 is selected as system clock */
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_LPIRC4M)
/*!
\brief configure the system clock to LPIRC4M
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_4m_lpirc4m(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable LPIRC4M */
RCU_ADDCTL1 |= RCU_ADDCTL1_LPIRC4MEN;
/* wait until LPIRC4M is stable or the startup time is longer than LPIRC4M_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB);
} while((0U == stab_flag) && (LPIRC4M_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB)) {
while(1) {
}
}
/* LPIRC4M is stable */
/* AHB = SYSCLK / 1*/
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB4 = AHB / 1 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1;
/* APB3 = AHB / 1 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 1 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
/* select LPIRC4M as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_LPIRC4M;
/* wait until LPIRC4M is selected as system clock */
while(RCU_SCSS_LPIRC4M != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_HXTAL)
/*!
\brief configure the system clock to HXTAL
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while(1) {
}
}
/* HXTAL is stable */
/* AHB = SYSCLK / 1*/
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB4 = AHB / 1 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1;
/* APB3 = AHB / 1 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 1 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
/* select HXTAL as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_HXTAL;
/* wait until HXTAL is selected as system clock */
while(RCU_SCSS_HXTAL != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL)
/*!
\brief configure the system clock to 200M by PLL0 which selects HXTAL as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_200m_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while(1) {
}
}
/* HXTAL is stable */
/* AHB = SYSCLK / 1 */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB4 = AHB / 2 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
/* APB3 = AHB / 2 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
/* PLL0 select HXTAL, configure PLL0 input and output range */
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M);
/* PLL0P = HXTAL / 5 * 40 = 200 MHz */
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
/* enable PLL0P, PLL0Q, PLL0R */
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
/* enable PLL0 */
RCU_CTL |= RCU_CTL_PLL0EN;
/* wait until PLL0 is stable */
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
}
/* select PLL0 as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
/* wait until PLL0 is selected as system clock */
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL)
/*!
\brief configure the system clock to 400M by PLL0 which selects HXTAL as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_400m_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while(1) {
}
}
/* insert TCM wait state at 400MHz */
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
/* HXTAL is stable */
/* AHB = SYSCLK / 1 */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
/* APB4 = AHB / 2 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
/* APB3 = AHB / 2 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
/* PLL0 select HXTAL, configure PLL0 input and output range */
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M);
/* PLL0P = HXTAL / 5 * 80 = 400 MHz */
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
/* enable PLL0P, PLL0Q, PLL0R */
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
/* enable PLL */
RCU_CTL |= RCU_CTL_PLL0EN;
/* wait until PLL0 is stable */
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
}
/* select PLL0 as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
/* wait until PLL0 is selected as system clock */
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL)
/*!
\brief configure the system clock to 480M by PLL0 which selects HXTAL as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_480m_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while(1) {
}
}
/* insert TCM wait state at 480MHz */
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
/* HXTAL is stable */
/* AHB = SYSCLK / 2 */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
/* APB4 = AHB / 2 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
/* APB3 = AHB / 2 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
/* PLL select HXTAL, configure PLL input and output range */
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLL0RNG_4M_8M);
/* PLL0P = HXTAL / 5 * 96 = 480 MHz */
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
/* enable PLL0P, PLL0Q, PLL0R */
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
/* enable PLL0 */
RCU_CTL |= RCU_CTL_PLL0EN;
/* wait until PLL0 is stable */
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
}
/* select PLL0 as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
/* wait until PLL0 is selected as system clock */
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL)
/*!
\brief configure the system clock to 600M by PLL0 which selects HXTAL as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_600m_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* if fail */
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while(1) {
}
}
/* insert TCM wait state at 600MHz */
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
/* HXTAL is stable */
/* AHB = SYSCLK / 2 */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
/* APB4 = AHB / 2 */
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
/* APB3 = AHB / 2 */
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
/* APB2 = AHB / 1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB / 2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
/* PLL select HXTAL, configure PLL input and output range */
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLL0RNG_4M_8M);
/* PLL0P = HXTAL / 5 * 120 = 600 MHz */
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
/* enable PLL0P, PLL0Q, PLL0R */
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
/* enable PLL0 */
RCU_CTL |= RCU_CTL_PLL0EN;
/* wait until PLL0 is stable */
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
}
/* select PLL0 as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
/* wait until PLL0 is selected as system clock */
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
}
}
#endif /* __SYSTEM_CLOCK_IRC64M */
/*!
\brief update the SystemCoreClock with current core clock retrieved from cpu registers
\param[in] none
\param[out] none
\retval none
*/
void SystemCoreClockUpdate(void)
{
uint32_t sws = 0U;
uint32_t irc64div = 0U;
uint32_t pllpsc = 0U, plln = 0U, pllp = 0U, pllsel = 0U;
sws = GET_BITS(RCU_CFG0, 2, 3);
switch(sws) {
/* IRC64M is selected as CK_SYS */
case SEL_IRC64MDIV:
irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17));
SystemCoreClock = IRC64M_VALUE / irc64div;
break;
/* HXTAL is selected as CK_SYS */
case SEL_LPIRC4M:
SystemCoreClock = LPIRC4M_VALUE;
break;
/* HXTAL is selected as CK_SYS */
case SEL_HXTAL:
SystemCoreClock = HXTAL_VALUE;
break;
/* PLL0P is selected as CK_SYS */
case SEL_PLL0P:
/* get the value of PLL0PSC[0,5], PLL0N[6,14], PLL0P[16,22] */
pllpsc = GET_BITS(RCU_PLL0, 0, 5);
plln = GET_BITS(RCU_PLL0, 6, 14) + 1U;
pllp = GET_BITS(RCU_PLL0, 16, 22) + 1U;
/* PLL clock source selection, HXTAL or IRC64M_VALUE or LPIRC4M_VALUE */
pllsel = GET_BITS(RCU_PLLALL, 16, 17);
if(0U == pllsel) {
irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17));
SystemCoreClock = (IRC64M_VALUE / irc64div / pllpsc) * plln / pllp;
} else if(1U == pllsel) {
SystemCoreClock = (LPIRC4M_VALUE / pllpsc) * plln / pllp;
} else {
SystemCoreClock = (HXTAL_VALUE / pllpsc) * plln / pllp;
}
break;
default:
/* should not be here */
break;
}
}
#ifdef __FIRMWARE_VERSION_DEFINE
/*!
\brief get firmware version
\param[in] none
\param[out] none
\retval firmware version
*/
uint32_t gd32h75e_firmware_version_get(void)
{
return __GD32H75E_STDPERIPH_VERSION;
}
#endif /* __FIRMWARE_VERSION_DEFINE */

446
828ECO/libraries/CMSIS/cachel1_armv7.h

@ -0,0 +1,446 @@
/******************************************************************************
* @file cachel1_armv7.h
* @brief CMSIS Level 1 Cache API for Armv7-M and later
* @version V1.0.3
* @date 17. March 2023
******************************************************************************/
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_CACHEL1_ARMV7_H
#define ARM_CACHEL1_ARMV7_H
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_CacheFunctions Cache Functions
\brief Functions that configure Instruction and Data cache.
@{
*/
/* Cache Size ID Register Macros */
#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos )
#ifndef __SCB_DCACHE_LINE_SIZE
#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
#ifndef __SCB_ICACHE_LINE_SIZE
#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
/**
\brief Enable I-Cache
\details Turns on I-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */
__DSB();
__ISB();
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable I-Cache
\details Turns off I-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate I-Cache
\details Invalidates I-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->ICIALLU = 0UL;
__DSB();
__ISB();
#endif
}
/**
\brief I-Cache Invalidate by address
\details Invalidates I-Cache for the given address.
I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
I-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] isize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if ( isize > 0 )
{
int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_ICACHE_LINE_SIZE;
op_size -= __SCB_ICACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief Enable D-Cache
\details Turns on D-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable D-Cache
\details Turns off D-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
struct {
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
} locals
#if ((defined(__GNUC__) || defined(__clang__)) && !defined(__OPTIMIZE__))
__ALIGNED(__SCB_DCACHE_LINE_SIZE)
#endif
;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
__DSB();
#if !defined(__OPTIMIZE__)
/*
* For the endless loop issue with no optimization builds.
* More details, see https://github.com/ARM-software/CMSIS_5/issues/620
*
* The issue only happens when local variables are in stack. If
* local variables are saved in general purpose register, then the function
* is OK.
*
* When local variables are in stack, after disabling the cache, flush the
* local variables cache line for data consistency.
*/
/* Clean and invalidate the local variable cache. */
#if defined(__ICCARM__)
/* As we can't align the stack to the cache line size, invalidate each of the variables */
SCB->DCCIMVAC = (uint32_t)&locals.sets;
SCB->DCCIMVAC = (uint32_t)&locals.ways;
SCB->DCCIMVAC = (uint32_t)&locals.ccsidr;
#else
SCB->DCCIMVAC = (uint32_t)&locals;
#endif
__DSB();
__ISB();
#endif
locals.ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
locals.sets = (uint32_t)(CCSIDR_SETS(locals.ccsidr));
do {
locals.ways = (uint32_t)(CCSIDR_WAYS(locals.ccsidr));
do {
SCB->DCCISW = (((locals.sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((locals.ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (locals.ways-- != 0U);
} while(locals.sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate D-Cache
\details Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean D-Cache
\details Cleans D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean & Invalidate D-Cache
\details Cleans and Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief D-Cache Invalidate by address
\details Invalidates D-Cache for the given address.
D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 )
{
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean by address
\details Cleans D-Cache for the given address
D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 )
{
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean and Invalidate by address
\details Cleans and invalidates D_Cache for the given address
D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned and invalidated.
\param[in] addr address (aligned to 32-byte boundary)
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 )
{
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/*@} end of CMSIS_Core_CacheFunctions */
#endif /* ARM_CACHEL1_ARMV7_H */

304
828ECO/libraries/CMSIS/cmsis_compiler.h

@ -0,0 +1,304 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.3.0
* @date 04. April 2023
******************************************************************************/
/*
* Copyright (c) 2009-2023 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6.6 LTM (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
#include "cmsis_armclang_ltm.h"
/*
* Arm Compiler above 6.10.1 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
#include "cmsis_armclang.h"
/*
* TI Arm Clang Compiler (tiarmclang)
*/
#elif defined (__ti__)
#include "cmsis_tiarmclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include <cmsis_iccarm.h>
/*
* TI Arm Compiler (armcl)
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed))T_UINT32
{ uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#ifndef __NO_INIT
#define __NO_INIT __attribute__ ((section (".bss.noinit")))
#endif
#ifndef __ALIAS
#define __ALIAS(x) __attribute__ ((alias(x)))
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#ifndef __NO_INIT
#define __NO_INIT __attribute__ ((section (".bss.noinit")))
#endif
#ifndef __ALIAS
#define __ALIAS(x) __attribute__ ((alias(x)))
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
/* NO RETURN is automatically detected hence no warning here*/
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#ifndef __NO_INIT
#define __NO_INIT __attribute__ ((section (".bss.noinit")))
#endif
#ifndef __ALIAS
#define __ALIAS(x) __attribute__ ((alias(x)))
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

2226
828ECO/libraries/CMSIS/cmsis_gcc.h

File diff suppressed because it is too large

40
828ECO/libraries/CMSIS/cmsis_version.h

@ -0,0 +1,40 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.5
* @date 02. February 2022
******************************************************************************/
/*
* Copyright (c) 2009-2022 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

2408
828ECO/libraries/CMSIS/core_cm7.h

File diff suppressed because it is too large

277
828ECO/libraries/CMSIS/mpu_armv7.h

@ -0,0 +1,277 @@
/******************************************************************************
* @file mpu_armv7.h
* @brief CMSIS MPU API for Armv7-M MPU
* @version V5.1.2
* @date 25. May 2020
******************************************************************************/
/*
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV7_H
#define ARM_MPU_ARMV7_H
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) /*/!< MPU Region Size 32 Bytes*/
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) /*/!< MPU Region Size 64 Bytes*/
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) /*/!< MPU Region Size 128 Bytes*/
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) /*/!< MPU Region Size 256 Bytes*/
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) /*/!< MPU Region Size 512 Bytes*/
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) /*/!< MPU Region Size 1 KByte*/
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) /*/!< MPU Region Size 2 KBytes*/
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) /*/!< MPU Region Size 4 KBytes*/
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) /*/!< MPU Region Size 8 KBytes*/
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) /*/!< MPU Region Size 16 KBytes*/
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) /*/!< MPU Region Size 32 KBytes*/
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) /*/!< MPU Region Size 64 KBytes*/
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) /*/!< MPU Region Size 128 KBytes*/
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) /*/!< MPU Region Size 256 KBytes*/
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) /*/!< MPU Region Size 512 KBytes*/
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) /*/!< MPU Region Size 1 MByte*/
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) /*/!< MPU Region Size 2 MBytes*/
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) /*/!< MPU Region Size 4 MBytes*/
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) /*/!< MPU Region Size 8 MBytes*/
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) /*/!< MPU Region Size 16 MBytes*/
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) /*/!< MPU Region Size 32 MBytes*/
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) /*/!< MPU Region Size 64 MBytes*/
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) /*/!< MPU Region Size 128 MBytes*/
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) /*/!< MPU Region Size 256 MBytes*/
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) /*/!< MPU Region Size 512 MBytes*/
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) /*/!< MPU Region Size 1 GByte*/
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) /*/!< MPU Region Size 2 GBytes*/
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) /*/!< MPU Region Size 4 GBytes*/
#define ARM_MPU_AP_NONE 0U /*/!< MPU Access Permission no access*/
#define ARM_MPU_AP_PRIV 1U /*/!< MPU Access Permission privileged access only*/
#define ARM_MPU_AP_URO 2U /*/!< MPU Access Permission unprivileged access read-only*/
#define ARM_MPU_AP_FULL 3U /*/!< MPU Access Permission full access*/
#define ARM_MPU_AP_PRO 5U /*/!< MPU Access Permission privileged access read-only*/
#define ARM_MPU_AP_RO 6U /*/!< MPU Access Permission read-only access*/
/** MPU Region Base Address Register Value
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress) \
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
((Region) & MPU_RBAR_REGION_Msk) | \
(MPU_RBAR_VALID_Msk))
/**
* MPU Memory Access Attributes
*
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
*/
#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \
((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
(((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
(((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
(((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \
((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
(((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
(((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
(((MPU_RASR_ENABLE_Msk))))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)
/**
* MPU Memory Access Attribute for strongly ordered memory.
* - TEX: 000b
* - Shareable
* - Non-cacheable
* - Non-bufferable
*/
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
/**
* MPU Memory Access Attribute for device memory.
* - TEX: 000b (if shareable) or 010b (if non-shareable)
* - Shareable or non-shareable
* - Non-cacheable
* - Bufferable (if shareable) or non-bufferable (if non-shareable)
*
* \param IsShareable Configures the device memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U))
/**
* MPU Memory Access Attribute for normal memory.
* - TEX: 1BBb (reflecting outer cacheability rules)
* - Shareable or non-shareable
* - Cacheable or non-cacheable (reflecting inner cacheability rules)
* - Bufferable or non-bufferable (reflecting inner cacheability rules)
*
* \param OuterCp Configures the outer cache policy.
* \param InnerCp Configures the inner cache policy.
* \param IsShareable Configures the memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U))
/**
* MPU Memory Access Attribute non-cacheable policy.
*/
#define ARM_MPU_CACHEP_NOCACHE 0U
/**
* MPU Memory Access Attribute write-back, write and read allocate policy.
*/
#define ARM_MPU_CACHEP_WB_WRA 1U
/**
* MPU Memory Access Attribute write-through, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WT_NWA 2U
/**
* MPU Memory Access Attribute write-back, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WB_NWA 3U
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; /*!< The region base address register value (RBAR)*/
uint32_t RASR; /*!< The region attribute and size register value (RASR) \ref MPU_RASR*/
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DMB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
MPU->RNR = rnr;
MPU->RASR = 0U;
}
/** Configure an MPU region.
* \param rbar Value for RBAR register.
* \param rasr Value for RASR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
{
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rasr Value for RASR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
{
MPU->RNR = rnr;
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load().
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
while (cnt > MPU_TYPE_RALIASES)
{
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
table += MPU_TYPE_RALIASES;
cnt -= MPU_TYPE_RALIASES;
}
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
}
#endif

799
828ECO/libraries/GD32H75E_standard_peripheral/Include/gd32h75e_adc.h

@ -0,0 +1,799 @@
/*!
\file gd32h75e_adc.h
\brief definitions for the ADC
\version 2025-08-07, V1.2.0, firmware for GD32H75E
*/
/*
Copyright (c) 2025, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef GD32H75E_ADC_H
#define GD32H75E_ADC_H
#include "gd32h75e.h"
/* ADC definitions */
#define ADC0 ADC_BASE /*!< ADC0 base address */
#define ADC1 (ADC_BASE + 0x00000400U) /*!< ADC1 base address */
#define ADC2 (ADC_BASE + 0x00000800U) /*!< ADC2 base address */
/* registers definitions */
#define ADC_STAT(adcx) REG32((adcx) + 0x00000000U) /*!< ADC status register */
#define ADC_CTL0(adcx) REG32((adcx) + 0x00000004U) /*!< ADC control register 0 */
#define ADC_CTL1(adcx) REG32((adcx) + 0x00000008U) /*!< ADC control register 1 */
#define ADC_IOFF0(adcx) REG32((adcx) + 0x0000000CU) /*!< ADC inserted channel data offset register 0 */
#define ADC_IOFF1(adcx) REG32((adcx) + 0x00000010U) /*!< ADC inserted channel data offset register 1 */
#define ADC_IOFF2(adcx) REG32((adcx) + 0x00000014U) /*!< ADC inserted channel data offset register 2 */
#define ADC_IOFF3(adcx) REG32((adcx) + 0x00000018U) /*!< ADC inserted channel data offset register 3 */
#define ADC_WDHT0(adcx) REG32((adcx) + 0x0000001CU) /*!< ADC watchdog high threshold register 0 */
#define ADC_WDLT0(adcx) REG32((adcx) + 0x00000020U) /*!< ADC watchdog low threshold register 0 */
#define ADC_RSQ0(adcx) REG32((adcx) + 0x00000024U) /*!< ADC routine sequence register 0 */
#define ADC_RSQ1(adcx) REG32((adcx) + 0x00000028U) /*!< ADC routine sequence register 1 */
#define ADC_RSQ2(adcx) REG32((adcx) + 0x0000002CU) /*!< ADC routine sequence register 2 */
#define ADC_RSQ3(adcx) REG32((adcx) + 0x00000030U) /*!< ADC routine sequence register 3 */
#define ADC_RSQ4(adcx) REG32((adcx) + 0x00000034U) /*!< ADC routine sequence register 4 */
#define ADC_RSQ5(adcx) REG32((adcx) + 0x00000038U) /*!< ADC routine sequence register 5 */
#define ADC_RSQ6(adcx) REG32((adcx) + 0x0000003CU) /*!< ADC routine sequence register 6 */
#define ADC_RSQ7(adcx) REG32((adcx) + 0x00000040U) /*!< ADC routine sequence register 7 */
#define ADC_RSQ8(adcx) REG32((adcx) + 0x00000044U) /*!< ADC routine sequence register 8 */
#define ADC_ISQ0(adcx) REG32((adcx) + 0x00000048U) /*!< ADC inserted sequence register 0 */
#define ADC_ISQ1(adcx) REG32((adcx) + 0x0000004CU) /*!< ADC inserted sequence register 1 */
#define ADC_ISQ2(adcx) REG32((adcx) + 0x00000050U) /*!< ADC inserted sequence register 2 */
#define ADC_IDATA0(adcx) REG32((adcx) + 0x00000054U) /*!< ADC inserted data register 0 */
#define ADC_IDATA1(adcx) REG32((adcx) + 0x00000058U) /*!< ADC inserted data register 1 */
#define ADC_IDATA2(adcx) REG32((adcx) + 0x0000005CU) /*!< ADC inserted data register 2 */
#define ADC_IDATA3(adcx) REG32((adcx) + 0x00000060U) /*!< ADC inserted data register 3 */
#define ADC_RDATA(adcx) REG32((adcx) + 0x00000064U) /*!< ADC routine data register */
#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x00000080U) /*!< ADC oversampling control register */
#define ADC_WD1SR(adcx) REG32((adcx) + 0x000000A0U) /*!< ADC watchdog 1 channel selection register */
#define ADC_WD2SR(adcx) REG32((adcx) + 0x000000A4U) /*!< ADC watchdog 2 channel selection register */
#define ADC_WDHT1(adcx) REG32((adcx) + 0x000000A8U) /*!< ADC watchdog high threshold register 1 */
#define ADC_WDLT1(adcx) REG32((adcx) + 0x000000ACU) /*!< ADC watchdog low threshold register 1 */
#define ADC_WDHT2(adcx) REG32((adcx) + 0x000000B0U) /*!< ADC watchdog high threshold register 2 */
#define ADC_WDLT2(adcx) REG32((adcx) + 0x000000B4U) /*!< ADC watchdog low threshold register 2 */
#define ADC_DIFCTL(adcx) REG32((adcx) + 0x000000B8U) /*!< ADC differential mode control register */
#define ADC_SSTAT REG32((ADC0) + 0x00000300U) /*!< ADC summary status register */
#define ADC_SYNCCTL(adcx) REG32((adcx) + 0x00000304U) /*!< ADC sync control register */
#define ADC_SYNCDATA0 REG32((ADC0) + 0x00000308U) /*!< ADC sync routine data register 0 */
#define ADC_SYNCDATA1 REG32((ADC0) + 0x0000030CU) /*!< ADC sync routine data register 1 */
/* bits definitions */
/* ADC_STAT */
#define ADC_STAT_WDE0 BIT(0) /*!< analog watchdog 0 event flag */
#define ADC_STAT_EOC BIT(1) /*!< end of sequence conversion flag */
#define ADC_STAT_EOIC BIT(2) /*!< end of inserted sequence conversion flag */
#define ADC_STAT_STIC BIT(3) /*!< start flag of inserted sequence */
#define ADC_STAT_STRC BIT(4) /*!< start flag of routine sequence */
#define ADC_STAT_ROVF BIT(5) /*!< routine data register overflow */
#define ADC_STAT_WDE1 BIT(30) /*!< analog watchdog 1 event flag */
#define ADC_STAT_WDE2 BIT(31) /*!< analog watchdog 2 event flag */
/* ADC_CTL0 */
#define ADC_CTL0_WD0CHSEL BITS(0,4) /*!< analog watchdog channel select */
#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */
#define ADC_CTL0_WDE0IE BIT(6) /*!< interrupt enable for WDE0 */
#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for EOIC */
#define ADC_CTL0_SM BIT(8) /*!< scan mode */
#define ADC_CTL0_WD0SC BIT(9) /*!< when in scan mode, analog watchdog 0 is effective on a single channel */
#define ADC_CTL0_ICA BIT(10) /*!< inserted sequence convert automatically */
#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on routine channels */
#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */
#define ADC_CTL0_DISNUM BITS(13,15) /*!< number of conversions in discontinuous mode */
#define ADC_CTL0_IWD0EN BIT(22) /*!< inserted channel analog watchdog 0 enable */
#define ADC_CTL0_RWD0EN BIT(23) /*!< routine channel analog watchdog 0 enable */
#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */
#define ADC_CTL0_ROVFIE BIT(26) /*!< interrupt enable for ROVF */
#define ADC_CTL0_WDE1IE BIT(30) /*!< interrupt enable for WDE1 */
#define ADC_CTL0_WDE2IE BIT(31) /*!< interrupt enable for WDE2 */
/* ADC_CTL1 */
#define ADC_CTL1_ADCON BIT(0) /*!< ADC on */
#define ADC_CTL1_CTN BIT(1) /*!< continuous mode */
#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */
#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */
#define ADC_CTL1_CALNUM BITS(4,6) /*!< ADC calibration times */
#define ADC_CTL1_DMA BIT(8) /*!< DMA request enable */
#define ADC_CTL1_DDM BIT(9) /*!< DMA disable mode */
#define ADC_CTL1_EOCM BIT(10) /*!< end of conversion mode */
#define ADC_CTL1_DAL BIT(11) /*!< data alignment */
#define ADC_CTL1_HPDFCFG BIT(12) /*!< HPDF mode configuration */
#define ADC_CTL1_ETMIC BITS(20,21) /*!< external trigger mode for inserted channels */
#define ADC_CTL1_SWICST BIT(22) /*!< software start on inserted channel */
#define ADC_CTL1_TSVEN1 BIT(23) /*!< temperature sensor channel enable */
#define ADC_CTL1_INREFEN BIT(24) /*!< vrefint channel enable */
#define ADC_CTL1_VBATEN BIT(25) /*!< vbat channel enable */
#define ADC_CTL1_CALMOD BIT(27) /*!< ADC calibration mode */
#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger mode for routine channels */
#define ADC_CTL1_SWRCST BIT(30) /*!< software start on routine channel. */
#define ADC_CTL1_TSVEN2 BIT(31) /*!< high-precision temperature sensor channel enable */
/* ADC_IOFFx x=0..3 */
#define ADC_IOFFX_IOFF BITS(0,23) /*!< data offset for inserted channel x */
/* ADC_WDHT0 */
#define ADC_WDHT0_WDHT0 BITS(0,23) /*!< high threshold for analog watchdog 0 */
/* ADC_WDLT0 */
#define ADC_WDLT0_WDLT0 BITS(0,23) /*!< low threshold for analog watchdog 0 */
/* ADC_RSQx x=0..8 */
#define ADC_RSQX_RSQN BITS(0,4) /*!< nth conversion channel number in the routine sequence */
#define ADC_RSQX_RSMPN BITS(5,14) /*!< nth conversion sample time in the routine sequence */
#define ADC_RSQ0_RL BITS(20,23) /*!< routine sequence length */
/* ADC_ISQx x=0..2 */
#define ADC_ISQX_ISQN BITS(0,4) /*!< nth conversion channel number in the inserted sequence */
#define ADC_ISQX_ISMPN BITS(5,14) /*!< nth conversion sample time in the inserted sequence */
#define ADC_ISQ0_IL BITS(20,21) /*!< inserted sequence length */
/* ADC_IDATAx x=0..3 */
#define ADC_IDATAX_IDATAN BITS(0,31) /*!< Inserted number n conversion data */
/* ADC_RDATA */
#define ADC_RDATA_RDATA BITS(0,31) /*!< routine channel data */
/* ADC_OVSAMPCTL */
#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */
#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */
#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */
#define ADC_OVSAMPCTL_OVSR BITS(16,25) /*!< oversampling ratio */
/* ADC_WD1SR */
#define ADC_WD1SR_AWD1CS BITS(0,21) /*!< analog watchdog 1 channel selection */
/* ADC_WD2SR */
#define ADC_WD2SR_AWD2CS BITS(0,21) /*!< analog watchdog 2 channel selection */
/* ADC_WDHT1 */
#define ADC_WDHT1_WDHT1 BITS(0,23) /*!< high threshold for analog watchdog 1 */
/* ADC_WDHT1 */
#define ADC_WDLT1_WDLT1 BITS(0,23) /*!< low threshold for analog watchdog 1 */
/* ADC_WDHT2 */
#define ADC_WDHT2_WDHT2 BITS(0,23) /*!< high threshold for analog watchdog 2 */
/* ADC_WDHT2 */
#define ADC_WDLT2_WDLT2 BITS(0,23) /*!< low threshold for analog watchdog 2 */
/* ADC_DIFCTL */
#define ADC_DIFCTL_DIFCTL BITS(0,21) /*!< Differential mode for channel 0..21 */
/* ADC_SSTAT */
#define ADC_SSTAT_ADC0_WDE0 BIT(0) /*!< the bit is mirror image of the WDE0 bit of ADC0 */
#define ADC_SSTAT_ADC0_WDE1 BIT(1) /*!< the bit is mirror image of the WDE1 bit of ADC0 */
#define ADC_SSTAT_ADC0_WDE2 BIT(2) /*!< the bit is mirror image of the WDE2 bit of ADC0 */
#define ADC_SSTAT_ADC0_EOC BIT(3) /*!< the bit is mirror image of the EOC bit of ADC0 */
#define ADC_SSTAT_ADC0_EOIC BIT(4) /*!< the bit is mirror image of the EOIC bit of ADC0 */
#define ADC_SSTAT_ADC0_STIC BIT(5) /*!< the bit is mirror image of the STIC bit of ADC0 */
#define ADC_SSTAT_ADC0_STRC BIT(6) /*!< the bit is mirror image of the STRC bit of ADC0 */
#define ADC_SSTAT_ADC0_ROVF BIT(7) /*!< the bit is mirror image of the ROVF bit of ADC0 */
#define ADC_SSTAT_ADC1_WDE0 BIT(8) /*!< the bit is mirror image of the WDE0 bit of ADC1 */
#define ADC_SSTAT_ADC1_WDE1 BIT(9) /*!< the bit is mirror image of the WDE1 bit of ADC1 */
#define ADC_SSTAT_ADC1_WDE2 BIT(10) /*!< the bit is mirror image of the WDE2 bit of ADC1 */
#define ADC_SSTAT_ADC1_EOC BIT(11) /*!< the bit is mirror image of the EOC bit of ADC1 */
#define ADC_SSTAT_ADC1_EOIC BIT(12) /*!< the bit is mirror image of the EOIC bit of ADC1 */
#define ADC_SSTAT_ADC1_STIC BIT(13) /*!< the bit is mirror image of the STIC bit of ADC1 */
#define ADC_SSTAT_ADC1_STRC BIT(14) /*!< the bit is mirror image of the STRC bit of ADC1 */
#define ADC_SSTAT_ADC1_ROVF BIT(15) /*!< the bit is mirror image of the ROVF bit of ADC1 */
#define ADC_SSTAT_ADC2_WDE0 BIT(16) /*!< the bit is mirror image of the WDE0 bit of ADC2 */
#define ADC_SSTAT_ADC2_WDE1 BIT(17) /*!< the bit is mirror image of the WDE1 bit of ADC2 */
#define ADC_SSTAT_ADC2_WDE2 BIT(18) /*!< the bit is mirror image of the WDE2 bit of ADC2 */
#define ADC_SSTAT_ADC2_EOC BIT(19) /*!< the bit is mirror image of the EOC bit of ADC2 */
#define ADC_SSTAT_ADC2_EOIC BIT(20) /*!< the bit is mirror image of the EOIC bit of ADC2 */
#define ADC_SSTAT_ADC2_STIC BIT(21) /*!< the bit is mirror image of the STIC bit of ADC2 */
#define ADC_SSTAT_ADC2_STRC BIT(22) /*!< the bit is mirror image of the STRC bit of ADC2 */
#define ADC_SSTAT_ADC2_ROVF BIT(23) /*!< the bit is mirror image of the ROVF bit of ADC2 */
/* ADC_SYNCCTL */
#define ADC_SYNCCTL_SYNCM BITS(0,3) /*!< ADC sync mode */
#define ADC_SYNCCTL_SYNCDLY BITS(8,11) /*!< ADC sync delay */
#define ADC_SYNCCTL_SYNCDDM BIT(13) /*!< ADC sync DMA disable mode */
#define ADC_SYNCCTL_SYNCDMA BITS(14,15) /*!< ADC sync DMA mode selection */
#define ADC_SYNCCTL_ADCSCK BITS(16,19) /*!< ADC sync clock mode */
#define ADC_SYNCCTL_ADCCK BITS(20,23) /*!< ADC clock prescaler */
/* ADC_SYNCDATA0 */
#define ADC_SYNCDATA0_SYNCDATA0 BITS(0,15) /*!< ADC0 routine data in ADC synchronization mode */
#define ADC_SYNCDATA0_SYNCDATA1 BITS(16,31) /*!< ADC1 routine data in ADC synchronization mode */
/* constants definitions */
/* ADC status flag */
#define ADC_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event flag */
#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion flag */
#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion flag */
#define ADC_FLAG_STIC ADC_STAT_STIC /*!< start flag of inserted sequence */
#define ADC_FLAG_STRC ADC_STAT_STRC /*!< start flag of routine sequence */
#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow */
#define ADC_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event flag */
#define ADC_FLAG_WDE2 ADC_STAT_WDE2 /*!< analog watchdog 2 event flag */
/* ADC interrupt */
#define ADC_INT_WDE0 ADC_CTL0_WDE0IE /*!< interrupt enable for WDE0 */
#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< interrupt enable for EOC */
#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< interrupt enable for EOIC */
#define ADC_INT_ROVF ADC_CTL0_ROVFIE /*!< interrupt enable for ROVF */
#define ADC_INT_WDE1 ADC_CTL0_WDE1IE /*!< interrupt enable for WDE1 */
#define ADC_INT_WDE2 ADC_CTL0_WDE2IE /*!< interrupt enable for WDE2 */
/* ADC interrupt flag */
#define ADC_INT_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event interrupt flag */
#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion interrupt flag */
#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion interrupt flag */
#define ADC_INT_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow interrupt flag */
#define ADC_INT_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event interrupt flag */
#define ADC_INT_FLAG_WDE2 ADC_STAT_WDE2 /*!< analog watchdog 2 event interrupt flag */
/* number of conversions in discontinuous mode */
#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) /*!< write value to ADC_CTL0_DISNUM bit field */
/* ADC special function definitions */
#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */
#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted sequence convert automatically */
#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */
/* ADC calibration mode */
#define ADC_CALIBRATION_OFFSET_MISMATCH ((uint32_t)0x00000000U) /*!< ADC calibration offset and mismatch mode */
#define ADC_CALIBRATION_OFFSET ADC_CTL1_CALMOD /*!< ADC calibration mode */
/* ADC calibration times */
#define CTL1_CALNUM(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) /*!< write value to ADC_CTL1_CLBNUM bit field */
#define ADC_CALIBRATION_NUM1 CTL1_CALNUM(0) /*!< ADC calibration 1 time */
#define ADC_CALIBRATION_NUM2 CTL1_CALNUM(1) /*!< ADC calibration 2 times */
#define ADC_CALIBRATION_NUM4 CTL1_CALNUM(2) /*!< ADC calibration 4 times */
#define ADC_CALIBRATION_NUM8 CTL1_CALNUM(3) /*!< ADC calibration 8 times */
#define ADC_CALIBRATION_NUM16 CTL1_CALNUM(4) /*!< ADC calibration 16 times */
#define ADC_CALIBRATION_NUM32 CTL1_CALNUM(5) /*!< ADC calibration 32 times */
/* ADC data alignment */
#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */
#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */
/* end of conversion mode */
#define ADC_EOC_SET_SEQUENCE ((uint32_t)0x00000000U) /*!< only at the end of a sequence of routine conversions, the EOC bit is set */
#define ADC_EOC_SET_CONVERSION ADC_CTL1_EOCM /*!< at the end of each routine conversion, the EOC bit is set */
/* ADC internal channel definitions */
#define ADC_CHANNEL_INTERNAL_TEMPSENSOR ADC_CTL1_TSVEN1 /*!< temperature sensor channel */
#define ADC_CHANNEL_INTERNAL_VREFINT ADC_CTL1_INREFEN /*!< vrefint channel */
#define ADC_CHANNEL_INTERNAL_VBAT ADC_CTL1_VBATEN /*!< vbat channel */
#define ADC_CHANNEL_INTERNAL_HP_TEMPSENSOR ADC_CTL1_TSVEN2 /*!< high-precision temperature sensor channel */
/* ADC data offset for inserted channel x */
#define IOFFX_IOFF(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_IOFFX_IOFF bit field */
/* ADC high threshold for analog watchdog 0 */
#define WDHT0_WDHT0(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT0_WDHT0 bit field */
/* ADC low threshold for analog watchdog 0 */
#define WDLT0_WDLT0(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT0_WDLT0 bit field */
/* ADC high threshold for analog watchdog 1 */
#define WDHT1_WDHT1(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT1_WDHT1 bit field */
/* ADC low threshold for analog watchdog 1 */
#define WDLT1_WDLT1(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT1_WDLT1 bit field */
/* ADC high threshold for analog watchdog 2 */
#define WDHT2_WDHT2(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT2_WDHT2 bit field */
/* ADC low threshold for analog watchdog 2 */
#define WDLT2_WDLT2(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT2_WDLT2 bit field */
/* ADC sequence sample time */
#define SQX_SMP(regval) (BITS(5,14) & ((uint32_t)(regval) << 5U)) /*!< write value to RSQX_SMPn or ISQX_SMPn bit field */
/* ADC routine sequence length */
#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_RSQ0_RL bit field */
/* ADC inserted sequence length */
#define ISQ0_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_ISQ0_IL bit field */
/* ADC resolution */
#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24U)) /*!< write value to ADC_CTL0_DRES bit field */
#define ADC_RESOLUTION_14B ((uint8_t)0x00U) /*!< 14-bit ADC resolution */
#define ADC_RESOLUTION_12B ((uint8_t)0x01U) /*!< 12-bit ADC resolution */
#define ADC_RESOLUTION_10B ((uint8_t)0x02U) /*!< 10-bit ADC resolution */
#define ADC_RESOLUTION_8B ((uint8_t)0x03U) /*!< 8-bit ADC resolution */
#define ADC_RESOLUTION_6B ((uint8_t)0x04U) /*!< 6-bit ADC resolution */
/* oversampling shift */
#define OVSCR_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5U)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */
#define ADC_OVERSAMPLING_SHIFT_NONE OVSCR_OVSS(0) /*!< no oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_1B OVSCR_OVSS(1) /*!< 1-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_2B OVSCR_OVSS(2) /*!< 2-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_3B OVSCR_OVSS(3) /*!< 3-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_4B OVSCR_OVSS(4) /*!< 4-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_5B OVSCR_OVSS(5) /*!< 5-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_6B OVSCR_OVSS(6) /*!< 6-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_7B OVSCR_OVSS(7) /*!< 7-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_8B OVSCR_OVSS(8) /*!< 8-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_9B OVSCR_OVSS(9) /*!< 9-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_10B OVSCR_OVSS(10) /*!< 10-bit oversampling shift */
#define ADC_OVERSAMPLING_SHIFT_11B OVSCR_OVSS(11) /*!< 11-bit oversampling shift */
/* oversampling ratio */
#define OVSCR_OVSR(regval) (BITS(16,25) & ((uint32_t)(regval) << 16U)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */
/* triggered oversampling */
#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */
#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */
/* configure the ADC clock */
#define SYNCCTL_ADCSCK(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) /*!< write value to ADC_SYNCCTL_ADCSCK bit field */
#define SYNCCTL_ADCCK(regval) (BITS(20,23) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_SYNCCTL_ADCCK bit field */
#define ADC_CLK_SYNC_HCLK_DIV2 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(8)) /*!< ADC sync clock mode HCLK div2 */
#define ADC_CLK_SYNC_HCLK_DIV4 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(9)) /*!< ADC sync clock mode HCLK div4 */
#define ADC_CLK_SYNC_HCLK_DIV6 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(10)) /*!< ADC sync clock mode HCLK div6 */
#define ADC_CLK_SYNC_HCLK_DIV8 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(11)) /*!< ADC sync clock mode HCLK div8 */
#define ADC_CLK_SYNC_HCLK_DIV10 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(12)) /*!< ADC sync clock mode HCLK div10 */
#define ADC_CLK_SYNC_HCLK_DIV12 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(13)) /*!< ADC sync clock mode HCLK div12 */
#define ADC_CLK_SYNC_HCLK_DIV14 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(14)) /*!< ADC sync clock mode HCLK div14 */
#define ADC_CLK_SYNC_HCLK_DIV16 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(15)) /*!< ADC sync clock mode HCLK div16 */
#define ADC_CLK_ASYNC_DIV1 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div1 */
#define ADC_CLK_ASYNC_DIV2 (SYNCCTL_ADCCK(1) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div2 */
#define ADC_CLK_ASYNC_DIV4 (SYNCCTL_ADCCK(2) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div4 */
#define ADC_CLK_ASYNC_DIV6 (SYNCCTL_ADCCK(3) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div6 */
#define ADC_CLK_ASYNC_DIV8 (SYNCCTL_ADCCK(4) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div8 */
#define ADC_CLK_ASYNC_DIV10 (SYNCCTL_ADCCK(5) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div10 */
#define ADC_CLK_ASYNC_DIV12 (SYNCCTL_ADCCK(6) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div12 */
#define ADC_CLK_ASYNC_DIV16 (SYNCCTL_ADCCK(7) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div16 */
#define ADC_CLK_ASYNC_DIV32 (SYNCCTL_ADCCK(8) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div32 */
#define ADC_CLK_ASYNC_DIV64 (SYNCCTL_ADCCK(9) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div64 */
#define ADC_CLK_ASYNC_DIV128 (SYNCCTL_ADCCK(10) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div128 */
#define ADC_CLK_ASYNC_DIV256 (SYNCCTL_ADCCK(11) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div256 */
/* ADC sync DMA mode selection */
#define SYNCCTL_SYNCDMA(regval) (BITS(14,15) & ((uint32_t)(regval) << 14U)) /*!< write value to ADC_SYNCCTL_SYNCDMA bit field */
#define ADC_SYNC_DMA_DISABLE SYNCCTL_SYNCDMA(0) /*!< ADC sync DMA disabled */
#define ADC_SYNC_DMA_MODE0 SYNCCTL_SYNCDMA(1) /*!< ADC sync DMA mode 0 */
#define ADC_SYNC_DMA_MODE1 SYNCCTL_SYNCDMA(2) /*!< ADC sync DMA mode 1 */
/* ADC sync delay */
#define SYNCCTL_SYNCDLY(regval) (BITS(8,11) & ((uint32_t)(regval) << 8U)) /*!< write value to ADC_SYNCCTL_SYNCDLY bit field */
#define ADC_SYNC_DELAY_5CYCLE SYNCCTL_SYNCDLY(0) /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */
#define ADC_SYNC_DELAY_6CYCLE SYNCCTL_SYNCDLY(1) /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */
#define ADC_SYNC_DELAY_7CYCLE SYNCCTL_SYNCDLY(2) /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */
#define ADC_SYNC_DELAY_8CYCLE SYNCCTL_SYNCDLY(3) /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */
#define ADC_SYNC_DELAY_9CYCLE SYNCCTL_SYNCDLY(4) /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */
#define ADC_SYNC_DELAY_10CYCLE SYNCCTL_SYNCDLY(5) /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */
#define ADC_SYNC_DELAY_11CYCLE SYNCCTL_SYNCDLY(6) /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */
#define ADC_SYNC_DELAY_12CYCLE SYNCCTL_SYNCDLY(7) /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */
#define ADC_SYNC_DELAY_13CYCLE SYNCCTL_SYNCDLY(8) /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */
#define ADC_SYNC_DELAY_14CYCLE SYNCCTL_SYNCDLY(9) /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */
#define ADC_SYNC_DELAY_15CYCLE SYNCCTL_SYNCDLY(10) /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */
#define ADC_SYNC_DELAY_16CYCLE SYNCCTL_SYNCDLY(11) /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */
#define ADC_SYNC_DELAY_17CYCLE SYNCCTL_SYNCDLY(12) /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */
#define ADC_SYNC_DELAY_18CYCLE SYNCCTL_SYNCDLY(13) /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */
#define ADC_SYNC_DELAY_19CYCLE SYNCCTL_SYNCDLY(14) /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */
#define ADC_SYNC_DELAY_20CYCLE SYNCCTL_SYNCDLY(15) /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */
/* ADC sync mode */
#define SYNCCTL_SYNCM(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_SYNCCTL_SYNCM bit field */
#define ADC_SYNC_MODE_INDEPENDENT SYNCCTL_SYNCM(0) /*!< ADC synchronization mode disabled.All the ADCs work independently */
#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(1) /*!< combined routine parallel & inserted parallel mode */
#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(2) /*!< combined routine parallel & trigger rotation mode */
#define ADC_DAUL_INSERTED_PARALLEL SYNCCTL_SYNCM(5) /*!< inserted parallel mode */
#define ADC_DAUL_ROUTINE_PARALLEL SYNCCTL_SYNCM(6) /*!< routine parallel mode */
#define ADC_DAUL_ROUTINE_FOLLOW_UP SYNCCTL_SYNCM(7) /*!< follow-up mode */
#define ADC_DAUL_INSERTED_TRIGGER_ROTATION SYNCCTL_SYNCM(9) /*!< trigger rotation mode */
/* external trigger mode for routine and inserted channel */
#define EXTERNAL_TRIGGER_DISABLE ((uint32_t)0x00000000U) /*!< external trigger disable */
#define EXTERNAL_TRIGGER_RISING ((uint32_t)0x00000001U) /*!< rising edge of external trigger */
#define EXTERNAL_TRIGGER_FALLING ((uint32_t)0x00000002U) /*!< falling edge of external trigger */
#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U) /*!< rising and falling edge of external trigger */
/* ADC channel definitions */
#define ADC_ROUTINE_CHANNEL ((uint8_t)0x01U) /*!< ADC routine sequence */
#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< ADC inserted sequence */
#define ADC_ROUTINE_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both routine and inserted sequence */
#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of routine & inserted channel */
/* ADC inserted channel definitions */
#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC inserted channel 0 */
#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC inserted channel 1 */
#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC inserted channel 2 */
#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC inserted channel 3 */
/* ADC channel definitions */
#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */
#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */
#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */
#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */
#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */
#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */
#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */
#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */
#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */
#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */
#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */
#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */
#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */
#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */
#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */
#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */
#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */
#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */
#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC channel 18 */
#define ADC_CHANNEL_19 ((uint8_t)0x13U) /*!< ADC channel 19 */
#define ADC_CHANNEL_20 ((uint8_t)0x14U) /*!< ADC channel 20 */
/* analog watchdog 1/2 channel selection for channel n(n=0..20) */
#define ADC_AWD1_2_SELECTION_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_16 ((uint32_t)0x00010000U) /*!< ADC channel 16 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_17 ((uint32_t)0x00020000U) /*!< ADC channel 17 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_18 ((uint32_t)0x00040000U) /*!< ADC channel 18 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_19 ((uint32_t)0x00080000U) /*!< ADC channel 19 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_20 ((uint32_t)0x00100000U) /*!< ADC channel 20 analog watchdog 1/2 selection */
#define ADC_AWD1_2_SELECTION_CHANNEL_ALL ((uint32_t)0x001FFFFFU) /*!< all ADC channels analog watchdog 1/2 selection */
/* Differential mode for channel n(n=0..21) */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_16 ((uint32_t)0x00010000U) /*!< ADC channel 16 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_17 ((uint32_t)0x00020000U) /*!< ADC channel 17 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_18 ((uint32_t)0x00040000U) /*!< ADC channel 18 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_19 ((uint32_t)0x00080000U) /*!< ADC channel 19 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_20 ((uint32_t)0x00100000U) /*!< ADC channel 20 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_21 ((uint32_t)0x00200000U) /*!< ADC channel 21 differential mode */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_ALL ((uint32_t)0x003FFFFFU) /*!< all ADC channels differential mode */
/* parameter check definitions */
#ifdef FW_DEBUG_ERR_REPORT
/* check the adc periph */
#define NOT_ADC_PERIPH(adc_periph) (((adc_periph) != ADC0) && ((adc_periph) != ADC1) && \
((adc_periph) != ADC2))
/* check the adc prescaler ratio */
#define NOT_ADC_CLK_MODE(prescaler) (((prescaler) != ADC_CLK_SYNC_HCLK_DIV2) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV4) && \
((prescaler) != ADC_CLK_SYNC_HCLK_DIV6) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV8) && \
((prescaler) != ADC_CLK_SYNC_HCLK_DIV10) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV12) && \
((prescaler) != ADC_CLK_SYNC_HCLK_DIV14) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV16) && \
((prescaler) != ADC_CLK_ASYNC_DIV1) && ((prescaler) != ADC_CLK_ASYNC_DIV2) && \
((prescaler) != ADC_CLK_ASYNC_DIV4) && ((prescaler) != ADC_CLK_ASYNC_DIV6) && \
((prescaler) != ADC_CLK_ASYNC_DIV8) && ((prescaler) != ADC_CLK_ASYNC_DIV10) && \
((prescaler) != ADC_CLK_ASYNC_DIV12) && ((prescaler) != ADC_CLK_ASYNC_DIV16) && \
((prescaler) != ADC_CLK_ASYNC_DIV32) && ((prescaler) != ADC_CLK_ASYNC_DIV64) && \
((prescaler) != ADC_CLK_ASYNC_DIV128) && ((prescaler) != ADC_CLK_ASYNC_DIV256))
/* check adc special mode */
#define ADC_SPECIAL_FUNCTION_LOW ((uint32_t)0x00000002U)
#define ADC_SPECIAL_FUNCTION_HIGH ((uint32_t)0x00000502U)
#define NOT_ADC_SPECIAL_FUNCTION_VALUE(function) ((ADC_SPECIAL_FUNCTION_LOW > (function)) || (ADC_SPECIAL_FUNCTION_HIGH < (function)))
/* check ENABLE and DISABLE */
#define NOT_ADC_ENABLE_DISABLE(newvalue) (((newvalue) != ENABLE) && ((newvalue) != DISABLE))
/* check data alignment */
#define NOT_ADC_DATA_ALIGNMENT(data_alignment) (((data_alignment) != ADC_DATAALIGN_RIGHT) && ((data_alignment) != ADC_DATAALIGN_LEFT))
/* check adc calibration mode */
#define NOT_CALIBRATION_MODE(clb_mode) (((clb_mode) != ADC_CALIBRATION_OFFSET_MISMATCH) && ((clb_mode) != ADC_CALIBRATION_OFFSET))
/* check adc calibration number */
#define NOT_ADC_CALIBRATION_NUMBER(clb_num) (((clb_num) != ADC_CALIBRATION_NUM1) && ((clb_num) != ADC_CALIBRATION_NUM2) && \
((clb_num) != ADC_CALIBRATION_NUM4) && ((clb_num) != ADC_CALIBRATION_NUM8) && \
((clb_num) != ADC_CALIBRATION_NUM16) && ((clb_num) != ADC_CALIBRATION_NUM32))
/* check ADC resolution */
#define NOT_ADC_RESOLUTION(resolution) (((resolution) != ADC_RESOLUTION_14B) && ((resolution) != ADC_RESOLUTION_12B) && ((resolution) \
!= ADC_RESOLUTION_10B) && ((resolution) != ADC_RESOLUTION_8B) && ((resolution) != ADC_RESOLUTION_6B))
/* check ADC resolution */
#define NOT_ADC_CHANNEL_INTERNAL(internal_channel) (((internal_channel) != ADC_CHANNEL_INTERNAL_TEMPSENSOR) && ((internal_channel) != ADC_CHANNEL_INTERNAL_VREFINT) && \
((internal_channel) != ADC_CHANNEL_INTERNAL_VBAT) && ((internal_channel) != ADC_CHANNEL_INTERNAL_HP_TEMPSENSOR))
/* check ADC sequence */
#define NOT_ADC_SEQUENCE(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL))
/* check discontinuous mode length */
#define ADC_DISCONTINUOUS_MODE_LENGTH_LOW ((uint32_t)0x00000001U)
#define ADC_DISCONTINUOUS_MODE_LENGTH_HIGH ((uint32_t)0x00000008U)
#define NOT_ADC_DISCONTINUOUS_MODE_LENGTH(length) ((ADC_DISCONTINUOUS_MODE_LENGTH_LOW > (length)) || (ADC_DISCONTINUOUS_MODE_LENGTH_HIGH < (length)))
/* check ADC sequence */
#define NOT_ADC_SEQUENCE(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL))
/* check ADC sequence */
#define NOT_ADC_SEQUENCE_EXD(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL)&& ((adc_sequence) != ADC_CHANNEL_DISCON_DISABLE))
/* check ADC channel length */
#define ADC_CHANNEL_LENGTH_LOW ((uint32_t)0x00000001U)
#define ADC_CHANNEL_LENGTH_HIGH ((uint32_t)0x00000010U)
#define NOT_ADC_CHANNEL_LENGTH(length) ((ADC_CHANNEL_LENGTH_LOW > (length)) || (ADC_CHANNEL_LENGTH_HIGH < (length)))
/* check routine sequence rank */
#define ADC_ROUTINE_SEQUENCE_RANK_HIGH ((uint32_t)0x0000000FU)
#define NOT_ADC_ROUTINE_SEQUENCE_RANK_VALUE(rank) (ADC_ROUTINE_SEQUENCE_RANK_HIGH < (rank))
/* check ADC channel select */
#define NOT_ADC_CHANNEL(channel) (((channel) != ADC_CHANNEL_0) && ((channel) != ADC_CHANNEL_1) && \
((channel) != ADC_CHANNEL_2) && ((channel) != ADC_CHANNEL_3) && \
((channel) != ADC_CHANNEL_4) && ((channel) != ADC_CHANNEL_5) && \
((channel) != ADC_CHANNEL_6) && ((channel) != ADC_CHANNEL_7) && \
((channel) != ADC_CHANNEL_8) && ((channel) != ADC_CHANNEL_9) && \
((channel) != ADC_CHANNEL_10) && ((channel) != ADC_CHANNEL_11) && \
((channel) != ADC_CHANNEL_12) && ((channel) != ADC_CHANNEL_13) && \
((channel) != ADC_CHANNEL_14) && ((channel) != ADC_CHANNEL_15) && \
((channel) != ADC_CHANNEL_16) && ((channel) != ADC_CHANNEL_17) && \
((channel) != ADC_CHANNEL_18) && ((channel) != ADC_CHANNEL_19) && \
((channel) != ADC_CHANNEL_20))
/* check ADC sample_time */
#define ADC_ADC_SAMPLE_TIME_HIGH ((uint32_t)0x00000329U)
#define NOT_ADC_SAMPLE_TIME(sample_time) (ADC_ADC_SAMPLE_TIME_HIGH < (sample_time))
/* check inserted sequence rank */
#define ADC_INSERTED_SEQUENCE_RANK_HIGH ((uint32_t)0x00000003U)
#define NOT_ADC_INSERTED_SEQUENCE_RANK_VALUE(rank) (ADC_INSERTED_SEQUENCE_RANK_HIGH < (rank))
/* check inserted channel */
#define NOT_INSERTED_CHANNEL(inserted_channel) (((inserted_channel) != ADC_INSERTED_CHANNEL_0) && ((inserted_channel) != ADC_INSERTED_CHANNEL_1) && \
((inserted_channel) != ADC_INSERTED_CHANNEL_2) && ((inserted_channel) != ADC_INSERTED_CHANNEL_3))
/* check inserted offset value */
#define ADC_INSERTED_OFFSET_HIGH ((uint32_t)0x00FFFFFFU)
#define NOT_ADC_INSERTED_OFFSET_VALUE(offset) (ADC_INSERTED_OFFSET_HIGH < (offset))
/* check ADC trigger mode */
#define NOT_ADC_TRIGGER_MODE(trigger_mode) (((trigger_mode) != EXTERNAL_TRIGGER_DISABLE) && ((trigger_mode) != EXTERNAL_TRIGGER_RISING) && \
((trigger_mode) != EXTERNAL_TRIGGER_FALLING) && ((trigger_mode) != EXTERNAL_TRIGGER_RISING_FALLING))
/* end of conversion mode */
#define NOT_ADC_END_OF_CONVERSION_MODE(end_selection) (((end_selection) != ADC_EOC_SET_SEQUENCE) && ((end_selection) != ADC_EOC_SET_CONVERSION))
/* check ADC sequence */
#define NOT_ADC_SEQUENC_BOTH(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL) && \
((adc_sequence) != ADC_ROUTINE_INSERTED_CHANNEL))
/* check differential mode for ADC channel */
#define ADC_DIFFERENTIAL_MODE_CHANNEL_LOW ((uint32_t)0x00000001U)
#define ADC_DIFFERENTIAL_MODE_CHANNEL_HIGH ((uint32_t)0x003FFFFFU)
#define NOT_ADC_DIFFERENTIAL_MODE_CHANNEL(length) ((ADC_DIFFERENTIAL_MODE_CHANNEL_LOW > (length)) || (ADC_DIFFERENTIAL_MODE_CHANNEL_HIGH < (length)))
/* check ADC analog watchdog 1/2 selection */
#define ADC_ANALOG_WATCHDOG_SEL_LOW ((uint32_t)0x00000001U)
#define ADC_ANALOG_WATCHDOG_SEL_HIGH ((uint32_t)0x001FFFFFU)
#define NOT_ADC_ANALOG_WATCHDOG_SEL(selection_channel) ((ADC_ANALOG_WATCHDOG_SEL_LOW > (selection_channel)) || (ADC_ANALOG_WATCHDOG_SEL_HIGH < (selection_channel)))
/* check analog watchdog threshold */
#define ADC_ANALOG_WATCHDOG_THRESHOLD_HIGH ((uint32_t)0x00FFFFFFU)
#define NOT_ADC_ANALOG_WATCHDOG_THRESHOLD(threshold) (ADC_ANALOG_WATCHDOG_THRESHOLD_HIGH < (threshold))
/* check ADC oversampling mode */
#define NOT_ADC_OVERSAMPLING_MODE(mode) (((mode) != ADC_OVERSAMPLING_ALL_CONVERT) && ((mode) != ADC_OVERSAMPLING_ONE_CONVERT))
/* check ADC oversampling shift */
#define NOT_ADC_OVERSAMPLING_SHIFT(shift) (((shift) != ADC_OVERSAMPLING_SHIFT_NONE) && ((shift) != ADC_OVERSAMPLING_SHIFT_1B) && \
((shift) != ADC_OVERSAMPLING_SHIFT_2B) && ((shift) != ADC_OVERSAMPLING_SHIFT_3B) && \
((shift) != ADC_OVERSAMPLING_SHIFT_4B) && ((shift) != ADC_OVERSAMPLING_SHIFT_5B) && \
((shift) != ADC_OVERSAMPLING_SHIFT_6B) && ((shift) != ADC_OVERSAMPLING_SHIFT_7B) && \
((shift) != ADC_OVERSAMPLING_SHIFT_8B) && ((shift) != ADC_OVERSAMPLING_SHIFT_9B) && \
((shift) != ADC_OVERSAMPLING_SHIFT_10B) && ((shift) != ADC_OVERSAMPLING_SHIFT_11B))
/* check ADC oversampling ratio */
#define ADC_OVERSAMPLING_RATIO_HIGH ((uint32_t)0x000003FFU)
#define NOT_ADC_OVERSAMPLING_RATIO(ratio) (ADC_OVERSAMPLING_RATIO_HIGH < (ratio))
/* check ADC falg */
#define NOT_ADC_FLAG(flag) (((flag) != ADC_FLAG_WDE0) && ((flag) != ADC_FLAG_EOC) && \
((flag) != ADC_FLAG_EOIC) && ((flag) != ADC_FLAG_STIC) && \
((flag) != ADC_FLAG_STRC) && ((flag) != ADC_FLAG_ROVF) && \
((flag) != ADC_FLAG_WDE1) && ((flag) != ADC_FLAG_WDE2))
/* check ADC interrupt */
#define NOT_ADC_INTERRUPT(interrupt) (((interrupt) != ADC_INT_WDE0) && ((interrupt) != ADC_INT_EOC) && \
((interrupt) != ADC_INT_EOIC) && ((interrupt) != ADC_INT_ROVF) && \
((interrupt) != ADC_INT_WDE1) && ((interrupt) != ADC_INT_WDE2))
/* check ADC interrupt flag */
#define NOT_ADC_INTERRUPT_FLAG(flag) (((int_flag) != ADC_INT_FLAG_WDE0) && ((int_flag) != ADC_INT_FLAG_EOC) && \
((int_flag) != ADC_INT_FLAG_EOIC) && ((int_flag) != ADC_INT_FLAG_ROVF) && \
((int_flag) != ADC_INT_FLAG_WDE1) && ((int_flag) != ADC_INT_FLAG_WDE2))
/* check the adc sync mode */
#define NOT_ADC_SYNC_mode(sync_mode) (((sync_mode) != ADC_SYNC_MODE_INDEPENDENT) && ((sync_mode) != ADC_DAUL_ROUTINE_PARALLEL_INSERTED_PARALLEL) && \
((sync_mode) != ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION) && ((sync_mode) != ADC_DAUL_INSERTED_PARALLEL) && \
((sync_mode) != ADC_DAUL_ROUTINE_PARALLEL) && ((sync_mode) != ADC_DAUL_ROUTINE_FOLLOW_UP) && \
((sync_mode) != ADC_DAUL_INSERTED_TRIGGER_ROTATION))
/* check the adc sync delay sample */
#define NOT_ADC_SYNC_DELAY_SAMPLE(sample_delay) (((sample_delay) != ADC_SYNC_DELAY_5CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_6CYCLE) && \
((sample_delay) != ADC_SYNC_DELAY_7CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_8CYCLE) && \
((sample_delay) != ADC_SYNC_DELAY_9CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_10CYCLE) && \
((sample_delay) != ADC_SYNC_DELAY_11CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_12CYCLE) && \
((sample_delay) != ADC_SYNC_DELAY_13CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_14CYCLE) && \
((sample_delay) != ADC_SYNC_DELAY_15CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_16CYCLE) && \
((sample_delay) != ADC_SYNC_DELAY_17CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_18CYCLE) && \
((sample_delay) != ADC_SYNC_DELAY_19CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_20CYCLE))
/* check the adc sync dma mode */
#define NOT_ADC_SYNC_DMA_mode(dma_mode) (((dma_mode) != ADC_SYNC_DMA_DISABLE) && ((dma_mode) != ADC_SYNC_DMA_MODE0) && \
((dma_mode) != ADC_SYNC_DMA_MODE1))
#endif /* FW_DEBUG_ERR_REPORT */
/* function declarations */
/* initialization config */
/* reset ADC */
void adc_deinit(uint32_t adc_periph);
/* configure the ADC clock */
void adc_clock_config(uint32_t adc_periph, uint32_t prescaler);
/* enable or disable ADC special function */
void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue);
/* configure ADC data alignment */
void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment);
/* enable ADC interface */
void adc_enable(uint32_t adc_periph);
/* disable ADC interface */
void adc_disable(uint32_t adc_periph);
/* configure ADC calibration mode */
void adc_calibration_mode_config(uint32_t adc_periph, uint32_t clb_mode);
/* configure ADC calibration number */
void adc_calibration_number(uint32_t adc_periph, uint32_t clb_num);
/* ADC calibration and reset calibration */
void adc_calibration_enable(uint32_t adc_periph);
/* configure ADC resolution */
void adc_resolution_config(uint32_t adc_periph, uint32_t resolution);
/* enable or disable ADC internal channels */
void adc_internal_channel_config(uint32_t internal_channel, ControlStatus newvalue);
/* DMA config */
/* enable DMA request */
void adc_dma_mode_enable(uint32_t adc_periph);
/* disable DMA request */
void adc_dma_mode_disable(uint32_t adc_periph);
/* when DMA=1, the DMA engine issues a request at end of each routine conversion */
void adc_dma_request_after_last_enable(uint32_t adc_periph);
/* the DMA engine is disabled after the end of transfer signal from DMA controller is detected */
void adc_dma_request_after_last_disable(uint32_t adc_periph);
/* enable hpdf mode */
void adc_hpdf_mode_enable(uint32_t adc_periph);
/* disable hpdf mode */
void adc_hpdf_mode_disable(uint32_t adc_periph);
/* routine sequence and inserted sequence config */
/* configure ADC discontinuous mode */
void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t length);
/* configure the length of routine sequence or inserted sequence */
void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t length);
/* configure ADC routine channel */
void adc_routine_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time);
/* configure ADC inserted channel */
void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time);
/* configure ADC inserted channel offset */
void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint32_t offset);
/* configure differential mode for channel */
void adc_channel_differential_mode_config(uint32_t adc_periph, uint32_t adc_channel, ControlStatus newvalue);
/* enable ADC external trigger */
void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t trigger_mode);
/* enable ADC software trigger */
void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_sequence);
/* configure end of conversion mode */
void adc_end_of_conversion_config(uint32_t adc_periph, uint32_t end_selection);
/* get channel data */
/* read ADC routine sequence data register */
uint32_t adc_routine_data_read(uint32_t adc_periph);
/* read ADC inserted sequence data register */
uint32_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel);
/* ADC analog watchdog functions */
/* configure ADC analog watchdog 0 single channel */
void adc_watchdog0_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel);
/* configure ADC analog watchdog 0 group channel */
void adc_watchdog0_group_channel_enable(uint32_t adc_periph, uint8_t adc_sequence);
/* disable ADC analog watchdog 0 */
void adc_watchdog0_disable(uint32_t adc_periph);
/* configure ADC analog watchdog 1 channel */
void adc_watchdog1_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue);
/* configure ADC analog watchdog 2 channel */
void adc_watchdog2_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue);
/* disable ADC analog watchdog 1 */
void adc_watchdog1_disable(uint32_t adc_periph);
/* disable ADC analog watchdog 2 */
void adc_watchdog2_disable(uint32_t adc_periph);
/* configure ADC analog watchdog 0 threshold */
void adc_watchdog0_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold);
/* configure ADC analog watchdog 1 threshold */
void adc_watchdog1_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold);
/* configure ADC analog watchdog 2 threshold */
void adc_watchdog2_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold);
/* ADC oversample functions */
/* configure ADC oversample mode */
void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint16_t ratio);
/* enable ADC oversample mode */
void adc_oversample_mode_enable(uint32_t adc_periph);
/* disable ADC oversample mode */
void adc_oversample_mode_disable(uint32_t adc_periph);
/* flag and interrupt functions */
/* get the ADC flag bits */
FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t flag);
/* clear the ADC flag bits */
void adc_flag_clear(uint32_t adc_periph, uint32_t flag);
/* enable ADC interrupt */
void adc_interrupt_enable(uint32_t adc_periph, uint32_t interrupt);
/* disable ADC interrupt */
void adc_interrupt_disable(uint32_t adc_periph, uint32_t interrupt);
/* get the ADC interrupt bits */
FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t int_flag);
/* clear the ADC flag */
void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t int_flag);
/* ADC synchronization */
/* configure the ADC sync mode */
void adc_sync_mode_config(uint32_t sync_mode);
/* configure the delay between 2 sampling phases in ADC sync modes */
void adc_sync_delay_config(uint32_t sample_delay);
/* configure ADC sync DMA mode selection */
void adc_sync_dma_config(uint32_t dma_mode);
/* configure ADC sync DMA engine issues requests according to the SYNCDMA bits */
void adc_sync_dma_request_after_last_enable(void);
/* configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected */
void adc_sync_dma_request_after_last_disable(void);
/* read ADC sync master adc routine data register 0 */
uint32_t adc_sync_master_adc_routine_data0_read(void);
/* read ADC sync slave adc routine data register 0 */
uint32_t adc_sync_slave_adc_routine_data0_read(void);
/* read ADC sync routine data register 1 */
uint32_t adc_sync_routine_data1_read(void);
#endif /* GD32H75E_ADC_H */

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save